home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume27 / distributed-c-2.1 / part14 < prev    next >
Encoding:
Text File  |  1993-12-22  |  57.8 KB  |  1,550 lines

  1. Newsgroups: comp.sources.unix
  2. From: pleierc@informatik.tu-muenchen.de (Christoph Pleier)
  3. Subject: v27i188: distributed-c-2.1 - Distributed C Development Environment, V2.1, Part14/18
  4. References: <1.756634932.28500@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: pleierc@informatik.tu-muenchen.de (Christoph Pleier)
  9. Posting-Number: Volume 27, Issue 188
  10. Archive-Name: distributed-c-2.1/part14
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 14 (of 18)."
  19. # Contents:  dcc/symb_process.c dcc/xdrfile.c
  20. # Wrapped by vixie@gw.home.vix.com on Thu Dec 23 00:12:05 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'dcc/symb_process.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'dcc/symb_process.c'\"
  24. else
  25. echo shar: Extracting \"'dcc/symb_process.c'\" \(29410 characters\)
  26. sed "s/^X//" >'dcc/symb_process.c' <<'END_OF_FILE'
  27. X/***************************************************************************
  28. X *                                                                         *
  29. X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
  30. X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
  31. X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
  32. X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
  33. X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
  34. X *                                                                         *
  35. X *              A compiler for distributed programming with C              *
  36. X *                                                                         *
  37. X *                       s y m b _ p r o c e s s . c                       *
  38. X *                                                                         *
  39. X *                            Package : Compiler                           *
  40. X *                            Version : 2.0                                *
  41. X *                       CreationDate : 01.08.90                           *
  42. X *                         LastUpDate : 08.06.91                           *
  43. X *                                                                         *
  44. X *    All functions handling symbol table information about processes.     *
  45. X *                                                                         *
  46. X *                  Portions Copyright 1990 Franz Distler                  *
  47. X *               Copyright (C) 1990-1994 by Christoph Pleier               *
  48. X *                          All rights reserved!                           *
  49. X ***************************************************************************/
  50. X
  51. X/*
  52. X * This file is part of the Distributed C Development Environment (DCDE).
  53. X * DCDE is free software; you can redistribute it and/or modify
  54. X * it under the terms written in the README-file. 
  55. X * DCDE is distributed in the hope that it will be useful,
  56. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  57. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  58. X * See the file README for more details.
  59. X */
  60. X
  61. X#include <stdio.h>
  62. X#include <ctype.h>
  63. X#include "config.h"
  64. X#include "extern.h"
  65. X#include "functions.h"
  66. X#include "y.tab.h" 
  67. X#include "com_Errno.h"
  68. X
  69. X/******************************************************************************
  70. X * make_process()                                                             *
  71. X *                                                                            *
  72. X * Initializes the symbol table element pointed to by 'symbol' as process     *
  73. X * specification.                                                             *
  74. X *                                                                            *
  75. X * Return values: 'symbol' upon success / NULL upon error                     *
  76. X ******************************************************************************/
  77. XSYMBTABEL *
  78. Xmake_process(symbol)
  79. XSYMBTABEL *symbol;
  80. X{
  81. X    if (errflag || !symbol) /* error handling */
  82. X    return(NULL);
  83. X#ifdef SYMBDEBUG
  84. X    fprintf(debugfile, "[symb] ***** make_process(): params: symbol = %d\n",
  85. X    symbol);
  86. X#endif /* SYMBDEBUG /**/
  87. X    if (symbol->type != UDEC) {
  88. X    strcpy(yytext, symbol->name);
  89. X    PRINTERROR("", EREDEFINITION);
  90. X    return(symbol);
  91. X    }
  92. X#ifdef SYMBDEBUG
  93. X    fprintf(debugfile, "[symb]       initializing entry \"%s\" as PROCESSDECL\n",
  94. X    symbol->name);
  95. X#endif /* SYMBDEBUG /**/
  96. X    symbol->type = PROCESSDECL;
  97. X    symbol->info.process.IsSpec     = TRUE;
  98. X    symbol->info.process.FirstParam = (SYMBTABEL *) NULL;
  99. X    symbol->info.process.FirstTrans = (SYMBTABEL *) NULL;
  100. X    return(symbol);
  101. X} /* make_process */
  102. X
  103. X/******************************************************************************
  104. X * make_process_def()                                                         *
  105. X *                                                                            *
  106. X * Initializes the symbol table element pointed to by 'symbol' as process     *
  107. X * defined.                                                                   *
  108. X *                                                                            *
  109. X * Return values: 'symbol' upon success / NULL upon error                     *
  110. X ******************************************************************************/
  111. XSYMBTABEL *
  112. Xmake_process_def(symbol)
  113. XSYMBTABEL *symbol;
  114. X{
  115. X    if (errflag || !symbol) /* error handling */
  116. X    return((SYMBTABEL *) NULL);
  117. X#ifdef SYMBDEBUG
  118. X    fprintf(debugfile, "[symb] ***** make_process_def(): params: symbol = %d\n",
  119. X    symbol);
  120. X#endif /* SYMBDEBUG /**/
  121. X    if (symbol->type != PROCESSDECL) {
  122. X    strcpy(yytext, symbol->name);
  123. X    PRINTERROR("", ENOTSPECIFIED);
  124. X    return(symbol);
  125. X    }
  126. X    if (symbol->info.process.IsSpec != TRUE) {
  127. X    strcpy(yytext, symbol->name);
  128. X    PRINTERROR("", EREDEFINED);
  129. X    return(symbol);
  130. X    }
  131. X#ifdef SYMBDEBUG
  132. X    fprintf(debugfile, "[symb]       marking process \"%s\" as defined\n",
  133. X    symbol->name);
  134. X#endif /* SYMBDEBUG /**/
  135. X    symbol->info.process.IsSpec = FALSE;
  136. X    return(symbol);
  137. X} /* make_process_def */
  138. X
  139. X/******************************************************************************
  140. X * make_parameter()                                                           *
  141. X *                                                                            *
  142. X * Marks the symbol table element pointed to by 'symbol' as parameter.        *
  143. X *                                                                            *
  144. X * Return values: 'symbol' upon success / NULL upon error                     *
  145. X ******************************************************************************/
  146. XSYMBTABEL *
  147. Xmake_parameter(symbol)
  148. Xregister SYMBTABEL *symbol;
  149. X{
  150. X    if (errflag || !symbol) /* error handling */
  151. X    return((SYMBTABEL *) NULL);
  152. X#ifdef SYMBDEBUG
  153. X    fprintf(debugfile, "[symb] ***** make_parameter(): params: symbol = %d\n",
  154. X    symbol);
  155. X#endif /* SYMBDEBUG /**/
  156. X    switch(symbol->type) {
  157. X    case UDEC:
  158. X    break;
  159. X    case PROCESSDECL:
  160. X    case TRANSACTION:
  161. X    case VARORPAR:
  162. X    case FUNCTIONDEF:
  163. X    case PROCESSVAR:
  164. X    case TYPEDEFNAME:
  165. X    case STRUCTDECL:
  166. X    if (symbol->blknum == blknum) {
  167. X        strcpy(yytext, symbol->name);
  168. X        PRINTERROR("", EREDEFINITION);
  169. X        return(symbol);
  170. X    } else
  171. X        symbol = enter_symbtabel(symbol->name);
  172. X    break;
  173. X    default:
  174. X    Panic("unknown kind of symbol table entry in make_parameter()");
  175. X    } /* switch */
  176. X#ifdef SYMBDEBUG
  177. X    fprintf(debugfile, "[symb]       marking \"%s\" as VARORPAR\n",
  178. X    symbol->name);
  179. X#endif /* SYMBDEBUG /**/
  180. X    symbol->type = VARORPAR;
  181. X    symbol->info.varorpar.DataType  = (DS_ATTR *)   NULL;
  182. X    symbol->info.varorpar.NextParam = (SYMBTABEL *) NULL;
  183. X    return(symbol);
  184. X} /* make_parameter */
  185. X
  186. X/******************************************************************************
  187. X * make_transaction()                                                         *
  188. X *                                                                            *
  189. X * Initializes the symbol table element pointed to by 'symbol' as transaction.*
  190. X *                                                                            *
  191. X * Return values: 'symbol' upon success / NULL upon error                     *
  192. X ******************************************************************************/
  193. XSYMBTABEL *
  194. Xmake_transaction(symbol)
  195. XSYMBTABEL *symbol;
  196. X{
  197. X    if (errflag || !symbol) /* error handling */
  198. X    return((SYMBTABEL *) NULL);
  199. X#ifdef SYMBDEBUG
  200. X    fprintf(debugfile, "[symb] ***** make_transaction(): params: symbol = %d\n",
  201. X    symbol);
  202. X#endif /* SYMBDEBUG /**/
  203. X    switch(symbol->type) {
  204. X    case UDEC:
  205. X    break;
  206. X    case PROCESSDECL:
  207. X    case TRANSACTION:
  208. X    case VARORPAR:
  209. X    case FUNCTIONDEF:
  210. X    case PROCESSVAR:
  211. X    case TYPEDEFNAME:
  212. X    case STRUCTDECL:
  213. X    if (symbol->blknum == blknum) {
  214. X        strcpy(yytext, symbol->name);
  215. X        PRINTERROR("", EREDEFINITION);
  216. X        return(symbol);
  217. X    } else
  218. X        symbol = enter_symbtabel(symbol->name);
  219. X    break;
  220. X    default:
  221. X    Panic("unknown kind of symbol table entry in make_transaction()");
  222. X    } /* switch */
  223. X#ifdef SYMBDEBUG
  224. X    fprintf(debugfile, "[symb]       initializing \"%s\" as TRANSACTION\n", 
  225. X    symbol->name);
  226. X#endif /* SYMBDEBUG /**/
  227. X    symbol->type = TRANSACTION;
  228. X    symbol->info.trans.IsDecl      = TRUE;
  229. X    symbol->info.trans.ReturnType  = (DS_ATTR *) NULL;
  230. X    symbol->info.trans.ptiname[0]  = '\0';
  231. X    symbol->info.trans.uptiname[0] = '\0';
  232. X    symbol->info.trans.Process     = (SYMBTABEL *) NULL;
  233. X    symbol->info.trans.FirstParam  = (SYMBTABEL *) NULL;
  234. X    symbol->info.trans.NextTrans   = (SYMBTABEL *) NULL;
  235. X    return(symbol);
  236. X} /* make_transaction */
  237. X
  238. X/******************************************************************************
  239. X * add_process_info()                                                         *
  240. X *                                                                            *
  241. X * Sets the pointers to the parameter list and the transaction list of a      *
  242. X * process specification symbol table element.                                *
  243. X *                                                                            *
  244. X * Return values: 'symbol' upon success / NULL upon error                     *
  245. X ******************************************************************************/
  246. XSYMBTABEL *
  247. Xadd_process_info(symbol, parameters, transactions)
  248. XSYMBTABEL *symbol, *parameters, *transactions;
  249. X{
  250. X    char *piname, *upiname, *hstr;
  251. X    static char extension[20];
  252. X
  253. X    if (errflag || !symbol) /* error handling */
  254. X    return((SYMBTABEL *) NULL);
  255. X#ifdef SYMBDEBUG
  256. X    fprintf(debugfile, "[symb] ***** add_process_info():\n");
  257. X    fprintf(debugfile, "[symb]       params: symbol = %d, parameters = %d\n", 
  258. X    symbol, parameters);
  259. X    fprintf(debugfile, "[symb]               transactions = %d\n",
  260. X    transactions);
  261. X#endif /* SYMBDEBUG /**/
  262. X    symbol->info.process.FirstParam = parameters;
  263. X    symbol->info.process.FirstTrans = transactions;
  264. X    /* 
  265. X     * determine process filename 
  266. X     */
  267. X    sprintf(extension, "_p%02d.c", ++processnum);
  268. X    hstr = symbol->info.process.filename;
  269. X    *hstr = hstr[MAXFILENAMELEN] = '\0';
  270. X    strncat(hstr, filenameprefix, MAXFILENAMELEN - strlen(extension));
  271. X    strcat(hstr, extension); 
  272. X    /* 
  273. X     * determine internal process names (used for naming) 
  274. X     */
  275. X    piname = symbol->info.process.piname;
  276. X    *piname = piname[MAXIDLEN - 2] = '\0';
  277. X    strncat(piname, symbol->name, MAXIDLEN - 2);
  278. X    upiname = symbol->info.process.upiname;
  279. X    strcpy(upiname, symbol->info.process.piname);
  280. X    for(; *upiname; ++upiname)
  281. X        *upiname = toupper(*upiname);
  282. X    /*
  283. X     * generate external declaration for include file
  284. X     */
  285. X    crextstr = Strcatmany(crextstr, 3, "extern PROCESSDESCR create_process_",
  286. X    piname, "();\n");
  287. X    return(symbol);
  288. X} /* add_process_info */
  289. X
  290. X/******************************************************************************
  291. X * add_trans_info()                                                           *
  292. X *                                                                            *
  293. X * Initializes the component 'piname' (process intern name).                  *
  294. X *                                                                            *
  295. X * Return values: 'symbol' upon success / NULL upon error                     *
  296. X ******************************************************************************/
  297. XSYMBTABEL *
  298. Xadd_trans_info(process, transactions)
  299. XSYMBTABEL *process, *transactions;
  300. X{
  301. X    register SYMBTABEL *actions;
  302. X    register char *hstr;
  303. X
  304. X    if (errflag || !process) /* error handling */
  305. X    return((SYMBTABEL *) NULL);
  306. X#ifdef SYMBDEBUG
  307. X    fprintf(debugfile, "[symb] ***** add_trans_info():\n");
  308. X    fprintf(debugfile, "[symb]       params: process = %d, transactions = %d\n",
  309. X    process, transactions);
  310. X    fprintf(debugfile, "[symb]       adding process pointer and internal names\n");
  311. X#endif /* SYMBDEBUG /**/
  312. X    for(actions=process->info.process.FirstTrans; actions; actions=actions->info.trans.NextTrans) {
  313. X        actions->info.trans.Process = process;
  314. X        /* determine transaction internal names (used for naming) */
  315. X        hstr = actions->info.trans.ptiname;
  316. X        *hstr = '\0';
  317. X        strncat(hstr, process->name, (int) (MAXIDLEN - 2) / 2);
  318. X        strcat(hstr, "_");
  319. X        strncat(hstr, actions->name, (int) (MAXIDLEN - 2) / 2);
  320. X        hstr[MAXIDLEN - 2] = '\0';
  321. X        hstr = actions->info.trans.uptiname;
  322. X        strcpy(hstr, actions->info.trans.ptiname);
  323. X        for(; *hstr; ++hstr)
  324. X        *hstr = toupper(*hstr);
  325. X#ifdef SYMBDEBUG
  326. X    fprintf(debugfile, "[symb]       transaction: \"%s\":\n", actions->name);
  327. X    fprintf(debugfile, "[symb]          ptiname = %s, uptiname = %s\n",
  328. X        actions->info.trans.ptiname, actions->info.trans.uptiname);
  329. X#endif /* SYMBDEBUG /**/
  330. X    *convert_buffer = 0;
  331. X    convert_buffer = convert_ds_to_string(convert_buffer, actions->info.trans.ReturnType);
  332. X        trextstr = Strcatmany(trextstr, 5, "extern ", convert_buffer, "call_", 
  333. X        actions->info.trans.ptiname, "();\n");
  334. X    } /* for */
  335. X    return(process);
  336. X} /* add_trans_info */
  337. X
  338. X/******************************************************************************
  339. X * add_transaction_info()                                                     *
  340. X *                                                                            *
  341. X * Sets the returntype and the pointer to the parameter list of a transaction *
  342. X * symbol table element.                                                      *
  343. X *                                                                            *
  344. X * Return values: 'symbol' upon success / NULL upon error                     *
  345. X ******************************************************************************/
  346. XSYMBTABEL *
  347. Xadd_transaction_info(symbol, type, first_param)
  348. XSYMBTABEL *symbol, 
  349. X          *first_param;
  350. XDS_ATTR   *type;
  351. X{
  352. X    if (errflag || !symbol) /* error handling */
  353. X    return((SYMBTABEL *) NULL);
  354. X#ifdef SYMBDEBUG
  355. X    fprintf(debugfile, "[symb] ***** add_transaction_info():\n");
  356. X    fprintf(debugfile, "[symb]       params: symbol = %d, type = %s, first_param = %d\n",
  357. X    symbol, type, first_param);
  358. X#endif /* SYMBDEBUG /**/
  359. X    symbol->info.trans.ReturnType = type;
  360. X    symbol->info.trans.FirstParam = first_param;
  361. X    return(symbol);
  362. X} /* add_transaction_info */
  363. X
  364. X/******************************************************************************
  365. X * add_transaction_label()                                                    *
  366. X *                                                                            *
  367. X * Sets the label number used for generating the end label of the transaction.*
  368. X *                                                                            *
  369. X * Return values: 'symbol' upon success / NULL upon error                     *
  370. X ******************************************************************************/
  371. XSYMBTABEL *
  372. Xadd_transaction_label(symbol)
  373. XSYMBTABEL *symbol;
  374. X{
  375. X    if (errflag || !symbol) /* error handling */
  376. X    return((SYMBTABEL *) NULL);
  377. X#ifdef SYMBDEBUG
  378. X    fprintf(debugfile, "[symb] ***** add_transaction_label():\n");
  379. X    fprintf(debugfile, "[symb]       params: symbol = %d\n", symbol);
  380. X#endif /* SYMBDEBUG /**/
  381. X    symbol->info.trans.labnum = ++translabel;
  382. X#ifdef SYMBDEBUG
  383. X    fprintf(debugfile, "[symb]       labnum = %d\n", translabel);
  384. X#endif /* SYMBDEBUG /**/
  385. X    return(symbol);
  386. X} /* add_transaction_info */
  387. X
  388. X/******************************************************************************
  389. X * add_parm_type()                                                            *
  390. X *                                                                            *
  391. X * Sets the type of a parameter in a parameter symbol table entry.            *
  392. X *                                                                            *
  393. X * Return values: 'symbol' upon success / NULL upon error                     *
  394. X ******************************************************************************/
  395. XSYMBTABEL *
  396. Xadd_parm_type(type, symbol)
  397. XDS_ATTR   *type;
  398. XSYMBTABEL *symbol;
  399. X{
  400. X    register SYMBTABEL *ptr;
  401. X
  402. X    if (errflag || !symbol) /* error handling */
  403. X    return((SYMBTABEL *) NULL);
  404. X#ifdef SYMBDEBUG
  405. X    fprintf(debugfile, "[symb] ***** add_parm_type(): params: type = %s, symbol = %d\n",
  406. X    type, symbol);
  407. X    *convert_buffer = 0;
  408. X    convert_buffer = convert_ds_to_string(convert_buffer, type);
  409. X    fprintf(debugfile, "[symb]       setting data type of \"%s\" to \"%s\"\n",
  410. X    symbol->name, convert_buffer);
  411. X#endif /* SYMBDEBUG /**/
  412. X    symbol->info.varorpar.DataType = type;
  413. X    return(symbol);
  414. X} /* add_parm_type */
  415. X
  416. X/******************************************************************************
  417. X * link_parameters()                                                          *
  418. X *                                                                            *
  419. X * Concatenates the parameter lists specified by 'symbol' and 'next'. The     *
  420. X * pointer to the resulting list is returned.                                 *
  421. X *                                                                            *
  422. X * Return values: 'symbol' upon success / NULL upon error                     *
  423. X ******************************************************************************/
  424. XSYMBTABEL *
  425. Xlink_parameters(symbol, next)
  426. XSYMBTABEL *symbol, *next;
  427. X{
  428. X    register SYMBTABEL *ptr;
  429. X
  430. X    if (errflag || !symbol) /* error handling */
  431. X    return((SYMBTABEL *) NULL);
  432. X#ifdef SYMBDEBUG
  433. X    fprintf(debugfile, "[symb] ***** link_parameters():\n");
  434. X    fprintf(debugfile, "[symb]       params: symbol = %d, next = %d\n",
  435. X    symbol,next);
  436. X#endif /* SYMBDEBUG /**/
  437. X    if (symbol->type != VARORPAR)
  438. X    Panic("argument for link_parameters() is no parameter");
  439. X    for(ptr=symbol; ptr->info.varorpar.NextParam; ptr=ptr->info.varorpar.NextParam)
  440. X    ;
  441. X#ifdef SYMBDEBUG
  442. X    fprintf(debugfile,"[symb]       linking \"%s\" (%d) to \"%s\" (%d)\n",
  443. X    ptr->name, ptr, next->name, next);
  444. X#endif /* SYMBDEBUG /**/
  445. X    ptr->info.varorpar.NextParam = next;
  446. X    return(symbol);
  447. X} /* link_parameters */
  448. X
  449. X/******************************************************************************
  450. X * link_transactions()                                                        *
  451. X *                                                                            *
  452. X * Concatenates the transaction lists specified by 'symbol' and 'next'. The   *
  453. X * pointer to the resulting list is returned.                                 *
  454. X *                                                                            *
  455. X * Return values: 'symbol' upon success / NULL upon error                     *
  456. X ******************************************************************************/
  457. XSYMBTABEL *
  458. Xlink_transactions(symbol, next)
  459. XSYMBTABEL *symbol, *next;
  460. X{
  461. X    register SYMBTABEL *ptr;
  462. X
  463. X    if (errflag || !symbol) /* error handling */
  464. X    return((SYMBTABEL *) NULL);
  465. X#ifdef SYMBDEBUG
  466. X    fprintf(debugfile, "[symb] ***** link_transactions():\n");
  467. X    fprintf(debugfile, "[symb]       params: symbol = %d, next = %d\n",
  468. X    symbol, next);
  469. X#endif /* SYMBDEBUG /**/
  470. X    if (symbol->type != TRANSACTION)
  471. X    Panic("argument for link_transactions() is no transaction");
  472. X    for(ptr=symbol; ptr->info.trans.NextTrans; ptr=ptr->info.trans.NextTrans)
  473. X    ;
  474. X#ifdef SYMBDEBUG
  475. X    fprintf(debugfile,"[symb]       linking \"%s\" (%d) to \"%s\" (%d)\n", 
  476. X    ptr->name, ptr, next->name, next);
  477. X#endif /* SYMBDEBUG /**/
  478. X    ptr->info.trans.NextTrans = next;
  479. X    return(symbol);
  480. X} /* link_transactions */
  481. X
  482. X/******************************************************************************
  483. X * reenter_process_comps                                                      *
  484. X *                                                                            *
  485. X * Rechains parameters and transactions of process specified by 'proc' in     *
  486. X * the symbol table.                                                          *
  487. X *                                                                            *
  488. X * Return values: none!                                                       *
  489. X ******************************************************************************/
  490. Xvoid
  491. Xreenter_process_comps(proc)
  492. XSYMBTABEL *proc;
  493. X{
  494. X    int hashid;
  495. X    register SYMBTABEL *ptr;
  496. X
  497. X    if (errflag || !proc) /* error handling! */
  498. X        return;
  499. X#ifdef SYMBDEBUG
  500. X    fprintf(debugfile, "[symb] ***** reenter_process_comps(): params: proc = %d\n",
  501. X    proc);
  502. X#endif /* SYMBDEBUG /**/
  503. X    /*
  504. X     * reenter process parameters
  505. X     */
  506. X    for(ptr = proc->info.process.FirstParam; ptr; ptr = ptr->info.varorpar.NextParam) {
  507. X#ifdef SYMBDEBUG
  508. X    fprintf(debugfile, "[symb]       reentering parameter \"%s\"\n",
  509. X        ptr->name);
  510. X#endif /* SYMBDEBUG /**/
  511. X    /* insert new element in PST list */
  512. X    ptr->PstNext           = symbtab.PstTab[blknum];
  513. X    symbtab.PstTab[blknum] = ptr;
  514. X    /* insert new element in ID list */
  515. X    hashid = hash(ptr->name);
  516. X    ptr->IdNext           = symbtab.IdTab[hashid];
  517. X    symbtab.IdTab[hashid] = ptr;
  518. X    }
  519. X    /*
  520. X     * reenter process transactions
  521. X     */
  522. X    for(ptr = proc->info.process.FirstTrans; ptr; ptr = ptr->info.trans.NextTrans) {
  523. X#ifdef SYMBDEBUG
  524. X    fprintf(debugfile, "[symb]       reentering transaction \"%s\"\n",
  525. X        ptr->name);
  526. X#endif /* SYMBDEBUG /**/
  527. X    /* insert new element in PST list */
  528. X    ptr->PstNext           = symbtab.PstTab[blknum];
  529. X    symbtab.PstTab[blknum] = ptr;
  530. X    /* insert new element in ID list */
  531. X    hashid = hash(ptr->name);
  532. X    ptr->IdNext           = symbtab.IdTab[hashid];
  533. X    symbtab.IdTab[hashid] = ptr;
  534. X    }
  535. X} /* reenter_process_comps */
  536. X
  537. X/******************************************************************************
  538. X * reenter_transaction_params()                                               *
  539. X *                                                                            *
  540. X * Rechains parameters and transactions of process specified by 'proc' in     *
  541. X * the symbol table.                                                          *
  542. X *                                                                            *
  543. X * Return values: none!                                                       *
  544. X ******************************************************************************/
  545. Xvoid
  546. Xreenter_transaction_params(trans)
  547. XSYMBTABEL *trans;
  548. X{
  549. X    int hashid;
  550. X    register SYMBTABEL *ptr;
  551. X
  552. X    if (errflag || !trans) /* error handling! */
  553. X        return;
  554. X#ifdef SYMBDEBUG
  555. X    fprintf(debugfile, "[symb] ***** reenter_transaction_params(): params: trans = %d\n",
  556. X    trans);
  557. X#endif /* SYMBDEBUG /**/
  558. X    for(ptr = trans->info.trans.FirstParam; ptr; ptr = ptr->info.varorpar.NextParam) {
  559. X#ifdef SYMBDEBUG
  560. X    fprintf(debugfile, "[symb]       reentering transaction parameter \"%s\"\n",
  561. X        ptr->name);
  562. X#endif /* SYMBDEBUG /**/
  563. X    /* insert new element in PST list */
  564. X    ptr->PstNext           = symbtab.PstTab[blknum];
  565. X    symbtab.PstTab[blknum] = ptr;
  566. X    /* insert new element in ID list */
  567. X    hashid = hash(ptr->name);
  568. X    ptr->IdNext           = symbtab.IdTab[hashid];
  569. X    symbtab.IdTab[hashid] = ptr;
  570. X    }
  571. X} /* reenter_transaction_params */
  572. X
  573. X/******************************************************************************
  574. X * is_process()                                                               *
  575. X *                                                                            *
  576. X * Checks and display an error message if 'Elem' was not declared as a        *
  577. X * process.                                                                   *
  578. X *                                                                            *
  579. X * Return values: none!                                                       *
  580. X ******************************************************************************/
  581. Xvoid
  582. Xis_process(Elem)
  583. XSYMBTABEL *Elem;
  584. X{
  585. X
  586. X    if (errflag || (!Elem))
  587. X    return;
  588. X#ifdef SYMBDEBUG
  589. X    fprintf(debugfile, "[symb] ***** is_process(): params: Elem = %d\n",
  590. X    Elem);
  591. X    fprintf(debugfile, "[symb]       checking if \"%s\" is a PROCESSDECL\n",
  592. X    Elem->name);
  593. X#endif /* SYMBDEBUG /**/
  594. X    if (Elem->type != PROCESSDECL) {
  595. X    strcpy(yytext, Elem->name);
  596. X    Errno = ENOTDEFINED;
  597. X    Error(NULL, "");
  598. X    return;
  599. X    }
  600. X} /* is_process */
  601. X
  602. X/******************************************************************************
  603. X * get_process()                                                              *
  604. X *                                                                            *
  605. X * Determines to a transaction name the corresponding process name.           *
  606. X *                                                                            *
  607. X * Return values: pointer to transaction upon success / NULL upon error       *
  608. X ******************************************************************************/
  609. XSYMBTABEL * 
  610. Xget_process(transaction)
  611. XSYMBTABEL *transaction;
  612. X{
  613. X    int decls = 0;
  614. X    SYMBTABEL *symbol, *actions, *result;
  615. X
  616. X    if (errflag || (!transaction))
  617. X    return(NULL);
  618. X#ifdef SYMBDEBUG
  619. X    fprintf(debugfile, "[symb] ***** get_process():\n");
  620. X    fprintf(debugfile, "[symb]       searching corresponding entry for \"%s\"\n",
  621. X    transaction->name);
  622. X#endif /* SYMBDEBUG /**/
  623. X    for(symbol = symbtab.PstTab[0]; symbol; symbol = symbol->PstNext) {
  624. X    if (symbol->type == PROCESSDECL) {
  625. X#ifdef SYMBDEBUG
  626. X        fprintf(debugfile, "[symb]       checking process \"%s\"\n",
  627. X        symbol->name);
  628. X#endif /* SYMBDEBUG /**/
  629. X            for(actions = symbol->info.process.FirstTrans; actions; 
  630. X                actions = actions->info.trans.NextTrans) {
  631. X        if (!strcmp(transaction->name, actions->name)) {
  632. X#ifdef SYMBDEBUG
  633. X                fputs("[symb]       found!\n", debugfile);
  634. X#endif /* SYMBDEBUG /**/
  635. X            if (!decls++)
  636. X            result = actions;
  637. X        }
  638. X        }
  639. X    }
  640. X    }
  641. X    if (!decls) {
  642. X    strcpy(yytext, transaction->name);
  643. X    Errno = ENOTDEFINED;
  644. X    Error(NULL, "");
  645. X    return(NULL);
  646. X    }
  647. X    if (decls > 1) {
  648. X    fprintf(stderr, "Warning: transaction \"%s\" is defined in more than one process!\n",
  649. X        transaction->name);
  650. X    fprintf(stderr, "         Please check if generated call matches process \"%s\"!\n",
  651. X        result->name);
  652. X    }
  653. X    return(result);
  654. X} /* get_process */
  655. X
  656. X/******************************************************************************
  657. X * check_transaction()                                                        *
  658. X *                                                                            *
  659. X * Checks the name of a transaction if this name is defined and unmistakable. *
  660. X *                                                                            *
  661. X * Return values: pointer to transaction upon success / NULL upon error       *
  662. X ******************************************************************************/
  663. XSYMBTABEL *
  664. Xcheck_transaction(transaction)
  665. XSYMBTABEL *transaction;
  666. X{
  667. X    int decls = 0;
  668. X    SYMBTABEL *symbol, *actions, *result;
  669. X
  670. X    if (errflag || (!transaction))
  671. X    return(NULL);
  672. X#ifdef SYMBDEBUG
  673. X    fprintf(debugfile, "[symb] ***** check_transaction():\n");
  674. X    fprintf(debugfile, "[symb]       searching corresponding entry for \"%s\"\n",
  675. X    transaction->name);
  676. X#endif /* SYMBDEBUG /**/
  677. X    for(symbol = symbtab.PstTab[0]; symbol; symbol = symbol->PstNext) {
  678. X    if (symbol->type == PROCESSDECL) {
  679. X#ifdef SYMBDEBUG
  680. X        fprintf(debugfile, "[symb]       checking process \"%s\"\n",
  681. X        symbol->name);
  682. X#endif /* SYMBDEBUG /**/
  683. X            for(actions = symbol->info.process.FirstTrans; actions; 
  684. X                actions = actions->info.trans.NextTrans) {
  685. X        if (!strcmp(transaction->name, actions->name)) {
  686. X#ifdef SYMBDEBUG
  687. X                fputs("[symb]       found!\n", debugfile);
  688. X#endif /* SYMBDEBUG /**/
  689. X            if (!decls++)
  690. X            result = actions;
  691. X        }
  692. X        }
  693. X    }
  694. X    }
  695. X    if (!decls) {
  696. X    strcpy(yytext, transaction->name);
  697. X    Errno = ENOTDEFINED;
  698. X    Error(NULL, "");
  699. X    return(NULL);
  700. X    }
  701. X    if (decls > 1) {
  702. X    fprintf(stderr, "Warning: Transaction \"%s\" is defined in more than one process!\n",
  703. X        transaction->name);
  704. X    fprintf(stderr, "         Please check if accept matches process \"%s\"!\n",
  705. X        result->name);
  706. X    }
  707. X    return(result);
  708. X} /* check_transaction */
  709. X
  710. X/******************************************************************************
  711. X * reenter_transactions()                                                     *
  712. X *                                                                            *
  713. X * Rechains transactions of idents in symbol table.                     *
  714. X *                                                                            *
  715. X * Return values: none!                                                       *
  716. X ******************************************************************************/
  717. Xvoid
  718. Xreenter_transactions(idents)
  719. XIDENTCHAIN *idents;
  720. X{
  721. X    int hashid;
  722. X    IDENTCHAIN *ptr;
  723. X    SYMBTABEL *symbolptr, *hptr;
  724. X
  725. X    if (errflag || (!idents))
  726. X    return;
  727. X#ifdef SYMBDEBUG 
  728. X    fprintf(debugfile, "[symb] ***** reenter_transactions():\n");
  729. X#endif /* SYMBDEBUG /**/
  730. X
  731. X    /* DIRTY PROGRAMMING! */
  732. X
  733. X/*
  734. X    for(ptr=idents; ptr; ptr = ptr->next) {
  735. X        if (ptr->symbol->type == PROCESSVAR) {
  736. X#ifdef SYMBDEBUG 
  737. X        fprintf(debugfile, "[symb]       ptr->symbol->name = %s\n",
  738. X        ptr->symbol->name);
  739. X#endif /* SYMBDEBUG /**/
  740. X/*
  741. X        symbolptr = ptr->symbol->info.varorpar.DataType->info.process;
  742. X        for (hptr = symbolptr->info.process.FirstTrans; hptr; 
  743. X                        hptr=hptr->info.trans.NextTrans) {
  744. X        if (!(lookup_symbtabel(hptr->name))) {
  745. X            /* insert new element in PST list */
  746. X/*
  747. X            hptr->PstNext          = symbtab.PstTab[blknum];
  748. X            symbtab.PstTab[blknum] = hptr;
  749. X            /* insert new element in ID list */
  750. X/*
  751. X            hashid = hash(hptr->name);
  752. X            hptr->IdNext          = symbtab.IdTab[hashid];
  753. X            symbtab.IdTab[hashid] = hptr;
  754. X        }
  755. X        }
  756. X        }
  757. X    }
  758. X*/
  759. X} /* reenter_transactions */
  760. END_OF_FILE
  761. if test 29410 -ne `wc -c <'dcc/symb_process.c'`; then
  762.     echo shar: \"'dcc/symb_process.c'\" unpacked with wrong size!
  763. fi
  764. # end of 'dcc/symb_process.c'
  765. fi
  766. if test -f 'dcc/xdrfile.c' -a "${1}" != "-c" ; then 
  767.   echo shar: Will not clobber existing file \"'dcc/xdrfile.c'\"
  768. else
  769. echo shar: Extracting \"'dcc/xdrfile.c'\" \(26041 characters\)
  770. sed "s/^X//" >'dcc/xdrfile.c' <<'END_OF_FILE'
  771. X/***************************************************************************
  772. X *                                                                         *
  773. X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
  774. X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
  775. X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
  776. X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
  777. X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
  778. X *                                                                         *
  779. X *              A compiler for distributed programming with C              *
  780. X *                                                                         *
  781. X *                            x d r f i l e . c                            *
  782. X *                                                                         *
  783. X *                            Package : Compiler                           *
  784. X *                            Version : 1.0                                *
  785. X *                       CreationDate : 25.09.91                           *
  786. X *                         LastUpDate : 05.11.91                           *
  787. X *                                                                         *
  788. X *                  The routine to generate the xdr file.                  *
  789. X *                                                                         *
  790. X *               Copyright (C) 1991-1994 by Christoph Pleier               *
  791. X *                          All rights reserved!                           *
  792. X ***************************************************************************/
  793. X
  794. X/*
  795. X * This file is part of the Distributed C Development Environment (DCDE).
  796. X * DCDE is free software; you can redistribute it and/or modify
  797. X * it under the terms written in the README-file. 
  798. X * DCDE is distributed in the hope that it will be useful,
  799. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  800. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  801. X * See the file README for more details.
  802. X */
  803. X
  804. X#if defined(HETEROGENEOUS) || defined(CHECK_XDR)
  805. X
  806. X#include <stdio.h>
  807. X#include <sys/types.h>
  808. X#ifndef CHECK_XDR
  809. X# include <rpc/rpc.h>
  810. X#endif
  811. X#include <string.h>
  812. X#include "config.h"
  813. X#include "extern.h"
  814. X#include "functions.h"
  815. X#include "ipc.h"
  816. X#include "dcc.h"
  817. X#include "com_Errno.h"
  818. X
  819. X/******************************************************************************
  820. X * print_dcc_buf_size_warning()                                               *
  821. X *                                                                            *
  822. X * Displays a warning about the size of the encode/decode buffer.             *
  823. X *                                                                            *
  824. X * Return values: none!                                                       *
  825. X ******************************************************************************/
  826. Xstatic int
  827. Xprint_dcc_buf_size_warning()
  828. X{
  829. X    if (!encode_warning) {
  830. X        fputs("Warning: Pointers are used within interprocess communication!\n", stderr);
  831. X        fputs("         Because the size of the buffer to store the encoded data\n", stderr);
  832. X        fputs("         can not be predicted at compilation time correctly, you\n", stderr);
  833. X        fputs("         may get problems during data conversion later.\n", stderr);
  834. X        fputs("         Better use option '-f <bufsize>' to specify a sufficent value!\n", stderr);
  835. X    encode_warning = TRUE;
  836. X    yynwarns++;
  837. X    }
  838. X} /* print_dcc_buf_size_warning */
  839. X
  840. X/******************************************************************************
  841. X * determine_xdr_routine()                                                    *
  842. X *                                                                            *
  843. X *    [signed, unsigned] [char, short, int, long]                             *
  844. X *                       float, double                                        *
  845. X *                                                                            *
  846. X * Return values: OK upon success / ERROR upon error                          *
  847. X ******************************************************************************/
  848. Xstatic int
  849. Xdetermine_xdr_routine(spec_qual_list, xdr_routine, type)
  850. XSQL_ATTR *spec_qual_list;
  851. Xchar **xdr_routine, **type;
  852. X{
  853. X    register int i;
  854. X    char *name;
  855. X    short elem_flag     = FALSE,
  856. X          signed_flag   = FALSE,
  857. X          unsigned_flag = FALSE;
  858. X    SYMBTABEL *symbol;
  859. X
  860. X#ifdef XDRDEBUG
  861. X    fputs("[code] ***** determine_xdr_routine():\n", debugfile);
  862. X#endif /* XDRDEBUG /**/
  863. X    for(; spec_qual_list; spec_qual_list = spec_qual_list->sq_list) {
  864. X    switch(spec_qual_list->type) {
  865. X    case SQL_ATTR_SPECIFIER:
  866. X        switch(spec_qual_list->info.type_specifier->type) {
  867. X        case TS_ATTR_VOID:
  868. X        Errno = EILLVOID;
  869. X        return(ERROR);
  870. X        /* break; */
  871. X        case TS_ATTR_CHAR:
  872. X        if (elem_flag) {
  873. X            Errno = EILLCHAR;
  874. X            return(ERROR);
  875. X        }
  876. X        *xdr_routine = (unsigned_flag) ? "u_char" : "char";
  877. X        *type        = (unsigned_flag) ? "unsigned char" : "char";
  878. X        elem_flag = TRUE;
  879. X        break;
  880. X        case TS_ATTR_SHORT:
  881. X        if (elem_flag) {
  882. X            Errno = EILLSHORT;
  883. X            return(ERROR);
  884. X        }
  885. X        *xdr_routine = (unsigned_flag) ? "u_short" : "short";
  886. X        *type        = (unsigned_flag) ? "unsigned short" : "short";
  887. X        elem_flag = TRUE;
  888. X        break;
  889. X        case TS_ATTR_INT:
  890. X        if (elem_flag) {
  891. X            Errno = EILLINT;
  892. X            return(ERROR);
  893. X        }
  894. X        *xdr_routine = (unsigned_flag) ? "u_int" : "int";
  895. X        *type        = (unsigned_flag) ? "unsigned int" : "int";
  896. X        elem_flag = TRUE;
  897. X        break;
  898. X        case TS_ATTR_LONG:
  899. X        if (elem_flag) {
  900. X            Errno = EILLLONG;
  901. X            return(ERROR);
  902. X        }
  903. X        *xdr_routine = (unsigned_flag) ? "u_long" : "long";
  904. X        *type        = (unsigned_flag) ? "unsigned long" : "long";
  905. X        elem_flag = TRUE;
  906. X        break;
  907. X        case TS_ATTR_FLOAT:
  908. X        if (elem_flag) {
  909. X            Errno = EILLFLOAT;
  910. X            return(ERROR);
  911. X        }
  912. X        *xdr_routine = *type = "float";
  913. X        elem_flag = TRUE;
  914. X        break;
  915. X        case TS_ATTR_DOUBLE:
  916. X        if (elem_flag) {
  917. X            Errno = EILLDOUBLE;
  918. X            return(ERROR);
  919. X        }
  920. X        *xdr_routine = *type = "double";
  921. X        elem_flag = TRUE;
  922. X        break;
  923. X        case TS_ATTR_PROCESS:
  924. X        if (elem_flag) {
  925. X            Errno = EILLPROCESS;
  926. X            return(ERROR);
  927. X        }
  928. X        *xdr_routine = *type = "PROCESSDESCR";
  929. X        elem_flag = TRUE;
  930. X        break;
  931. X        case TS_ATTR_SIGNED:
  932. X        if (unsigned_flag) {
  933. X            Errno = EILLSIGNED;
  934. X            return(ERROR);
  935. X        }
  936. X        signed_flag = TRUE;
  937. X        break;
  938. X        case TS_ATTR_UNSIGNED:
  939. X        if (signed_flag) {
  940. X            Errno = EILLUNSIGNED;
  941. X            return(ERROR);
  942. X        }
  943. X        unsigned_flag = TRUE;
  944. X        break;
  945. X        case TS_ATTR_ENUM:
  946. X        Errno = EILLENUM;
  947. X        return(ERROR);
  948. X        break;
  949. X        case TS_ATTR_STRUCT:
  950. X        if (unsigned_flag) {
  951. X            Errno = EILLSIGNED;
  952. X            return(ERROR);
  953. X        }
  954. X        if (signed_flag) {
  955. X            Errno = EILLUNSIGNED;
  956. X            return(ERROR);
  957. X        }
  958. X            name = spec_qual_list->info.type_specifier->info.structinfo->tag->name;
  959. X            *xdr_routine = name;
  960. X        *type = (char *) Malloc(strlen("struct " + strlen(name) + 1));
  961. X        sprintf(*type, "struct %s", name);
  962. X        break;
  963. X        case TS_ATTR_TYPENAME:
  964. X            *xdr_routine = *type = spec_qual_list->info.type_specifier->info.typedefname->name;
  965. X        break;
  966. X        default:
  967. X            Panic("illegal TS_ATTR type in determine_xdr_routine()");
  968. X        } /* switch */
  969. X        break;
  970. X    case SQL_ATTR_QUALIFIER:
  971. X        if (spec_qual_list->info.type_qualifier->type == TQ_ATTR_CONST)
  972. X            Errno = EILLCONST;
  973. X        else
  974. X            Errno = EILLVOLATILE;
  975. X        return(ERROR);
  976. X        break;
  977. X    default:
  978. X        Panic("illegal SQL_ATTR type in determine_xdr_routine()");
  979. X    } /* switch */
  980. X    }
  981. X    return(OK);
  982. X} /* determine_xdr_routine */
  983. X
  984. X/******************************************************************************
  985. X * determine_typedef_xdr_routine()                                            *
  986. X *                                                                            *
  987. X *    [signed, unsigned] [char, short, int, long]                             *
  988. X *                       float, double                                        *
  989. X *                                                                            *
  990. X * Return values: OK upon success / ERROR upon error                          *
  991. X ******************************************************************************/
  992. Xstatic int
  993. Xdetermine_typedef_xdr_routine(ds_attr, xdr_routine, type)
  994. XDS_ATTR *ds_attr;    /* declaration specifiers attribute */
  995. Xchar **xdr_routine, **type;
  996. X{
  997. X    register int i;
  998. X    char *name;
  999. X    short elem_flag     = FALSE,
  1000. X          signed_flag   = FALSE,
  1001. X          unsigned_flag = FALSE;
  1002. X    SYMBTABEL *symbol;
  1003. X
  1004. X#ifdef XDRDEBUG
  1005. X    fputs("[code] ***** determine_typedef_xdr_routine():\n", debugfile);
  1006. X#endif /* XDRDEBUG /**/
  1007. X
  1008. X    for(; ds_attr; ds_attr = ds_attr->ds) {
  1009. X
  1010. X    /* check if there is a storage class specifier in the type definition.
  1011. X     * auto, register, static, extern or typedef are not allowed here! 
  1012. X     */
  1013. X    if (ds_attr->scs) {
  1014. X        switch(ds_attr->scs->type) {
  1015. X        case SCS_ATTR_AUTO:
  1016. X        Errno = EILLAUTO;
  1017. X        break;
  1018. X        case SCS_ATTR_REGISTER:
  1019. X        Errno = EILLREGISTER;
  1020. X        break;
  1021. X        case SCS_ATTR_STATIC:
  1022. X        Errno = EILLSTATIC;
  1023. X        break;
  1024. X        case SCS_ATTR_EXTERN:
  1025. X        Errno = EILLEXTERN;
  1026. X        break;
  1027. X        case SCS_ATTR_TYPEDEF:
  1028. X        Errno = EILLTYPEDEF;
  1029. X        break;
  1030. X            default:
  1031. X            Panic("illegal SCS_ATTR type in determine_typedef_xdr_routine()");
  1032. X            } /* switch */
  1033. X        return(ERROR);
  1034. X    }
  1035. X
  1036. X    /* check if there is a type qualifier in the type definition.
  1037. X     * const or volatile are not allowed here! 
  1038. X     */
  1039. X    if (ds_attr->tq) {
  1040. X        switch(ds_attr->tq->type) {
  1041. X        case TQ_ATTR_CONST:
  1042. X        Errno = EILLCONST2;
  1043. X        break;
  1044. X        case TQ_ATTR_VOLATILE:
  1045. X        Errno = EILLVOLATILE2;
  1046. X        break;
  1047. X        default:
  1048. X               Panic("illegal TQ_ATTR type in determine_typedef_xdr_routine()");
  1049. X        } /* switch */
  1050. X        return(ERROR);
  1051. X    }
  1052. X
  1053. X    switch(ds_attr->ts->type) {
  1054. X    case TS_ATTR_VOID:
  1055. X        Errno = EILLVOID2;
  1056. X        return(ERROR);
  1057. X        /* break; */
  1058. X    case TS_ATTR_CHAR:
  1059. X        if (elem_flag) {
  1060. X            Errno = EILLCHAR;
  1061. X            return(ERROR);
  1062. X        }
  1063. X        *xdr_routine = (unsigned_flag) ? "u_char" : "char";
  1064. X        *type        = (unsigned_flag) ? "unsigned char" : "char";
  1065. X        elem_flag = TRUE;
  1066. X        break;
  1067. X        case TS_ATTR_SHORT:
  1068. X        if (elem_flag) {
  1069. X            Errno = EILLSHORT;
  1070. X            return(ERROR);
  1071. X        }
  1072. X        *xdr_routine = (unsigned_flag) ? "u_short" : "short";
  1073. X        *type        = (unsigned_flag) ? "unsigned short" : "short";
  1074. X        elem_flag = TRUE;
  1075. X        break;
  1076. X        case TS_ATTR_INT:
  1077. X        if (elem_flag) {
  1078. X            Errno = EILLINT;
  1079. X            return(ERROR);
  1080. X        }
  1081. X        *xdr_routine = (unsigned_flag) ? "u_int" : "int";
  1082. X        *type        = (unsigned_flag) ? "unsigned int" : "int";
  1083. X        elem_flag = TRUE;
  1084. X        break;
  1085. X        case TS_ATTR_LONG:
  1086. X        if (elem_flag) {
  1087. X            Errno = EILLLONG;
  1088. X            return(ERROR);
  1089. X        }
  1090. X        *xdr_routine = (unsigned_flag) ? "u_long" : "long";
  1091. X        *type        = (unsigned_flag) ? "unsigned long" : "long";
  1092. X        elem_flag = TRUE;
  1093. X        break;
  1094. X        case TS_ATTR_FLOAT:
  1095. X        if (elem_flag) {
  1096. X            Errno = EILLFLOAT;
  1097. X            return(ERROR);
  1098. X        }
  1099. X        *xdr_routine = *type = "float";
  1100. X        elem_flag = TRUE;
  1101. X        break;
  1102. X        case TS_ATTR_DOUBLE:
  1103. X        if (elem_flag) {
  1104. X            Errno = EILLDOUBLE;
  1105. X            return(ERROR);
  1106. X        }
  1107. X        *xdr_routine = *type = "double";
  1108. X        elem_flag = TRUE;
  1109. X        break;
  1110. X        case TS_ATTR_PROCESS:
  1111. X        if (elem_flag) {
  1112. X            Errno = EILLPROCESS;
  1113. X            return(ERROR);
  1114. X        }
  1115. X        *xdr_routine = *type = "PROCESSDESCR";
  1116. X        elem_flag = TRUE;
  1117. X        break;
  1118. X        case TS_ATTR_SIGNED:
  1119. X       if (unsigned_flag) {
  1120. X        Errno = EILLSIGNED;
  1121. X            return(ERROR);
  1122. X        }
  1123. X        signed_flag = TRUE;
  1124. X        break;
  1125. X        case TS_ATTR_UNSIGNED:
  1126. X        if (signed_flag) {
  1127. X        Errno = EILLUNSIGNED;
  1128. X            return(ERROR);
  1129. X        }
  1130. X        unsigned_flag = TRUE;
  1131. X        break;
  1132. X        case TS_ATTR_ENUM:
  1133. X        Errno = EILLENUM2;
  1134. X        return(ERROR);
  1135. X        break;
  1136. X        case TS_ATTR_STRUCT:
  1137. X        if (unsigned_flag) {
  1138. X            Errno = EILLSIGNED;
  1139. X            return(ERROR);
  1140. X        }
  1141. X        if (signed_flag) {
  1142. X            Errno = EILLUNSIGNED;
  1143. X            return(ERROR);
  1144. X        }
  1145. X            if (!ds_attr->ts->info.structinfo->tag) {
  1146. X        Errno = ETSTRUCTTAG;
  1147. X        return(ERROR);
  1148. X        }
  1149. X            name = ds_attr->ts->info.structinfo->tag->name;
  1150. X        *xdr_routine = name;
  1151. X        *type = (char *) Malloc(strlen("struct " + strlen(name) + 1));
  1152. X        sprintf(*type, "struct %s", name);
  1153. X        break;
  1154. X        case TS_ATTR_TYPENAME:
  1155. X            *xdr_routine = *type = ds_attr->ts->info.typedefname->name;
  1156. X        break;
  1157. X        default:
  1158. X            Panic("illegal TS_ATTR type in determine_typedef_xdr_routine()");
  1159. X        } /* switch */
  1160. X
  1161. X    } /* for(ds_attr) */
  1162. X    return(OK);
  1163. X} /* determine_typedef_xdr_routine */
  1164. X
  1165. X/******************************************************************************
  1166. X * build_xdrfile()                                                            *
  1167. X *                                                                            *
  1168. X * Valid elementar types are:                                                 *
  1169. X *                                                                            *
  1170. X *    [signed, unsigned] [char, short, int, long]                             *
  1171. X *                       float, double                                        *
  1172. X *                                                                            *
  1173. X * Return values: always OK for success                                       *
  1174. X ******************************************************************************/
  1175. Xint
  1176. Xbuild_xdrfile()
  1177. X{
  1178. X    int i, length, signed_flag, unsigned_flag, pointer_flag;
  1179. X    char *xdr_name, *type;
  1180. X    char *hstr;
  1181. X    register SYMBTABEL *sptr, *actions, *params;
  1182. X    register struct struct_type_list *stlptr;
  1183. X    register struct include_list *inclptr;
  1184. X    ST_ATTR *st_attr;
  1185. X    STL_ATTR *stl_attr;
  1186. X    SD_ATTR *sd_attr;
  1187. X    SDL_ATTR *sdl_attr;
  1188. X    D_ATTR *d_attr;
  1189. X    DD_ATTR *dd_attr, *dd_attr2;
  1190. X    DS_ATTR *ds_attr, *ds_attr2;
  1191. X
  1192. X#ifdef XDRDEBUG
  1193. X    fputs("[code] ***** build_xdrfile():\n", debugfile);
  1194. X    display_struct_type_list();
  1195. X#endif /* XDRDEBUG /**/
  1196. X    if (infoflag) {
  1197. X    printf("%s building the xdrfile\n", infoprefix);
  1198. X    fflush(stdout);
  1199. X    }
  1200. X
  1201. X    /* 
  1202. X     * create file 
  1203. X     */
  1204. X    (void) strcpy(xdrfilename, filenameprefix);
  1205. X    length = MAXFILENAMELEN - strlen(XDRFILEEXT);
  1206. X    if (strlen(filenameprefix) <= length)
  1207. X        (void) strcat(xdrfilename, XDRFILEEXT);
  1208. X    else
  1209. X        (void) strcpy(&xdrfilename[length], XDRFILEEXT);
  1210. X    if (!(xdrfile = fopen(xdrfilename, "w"))) {
  1211. X        fprintf(stderr,"Error: impossible to open file for xdr routines '%s'\n",
  1212. X            xdrfilename);
  1213. X        exit(EXIT_FOPEN);
  1214. X    }
  1215. X    /* 
  1216. X     * write header to file 
  1217. X     */
  1218. X    fprintf(xdrfile, "/* %s */\n\n", xdrfilename);
  1219. X    fputs("/*\n", xdrfile);
  1220. X    for(i = 0; *headerstr[i]; ++i)
  1221. X        fprintf(xdrfile, " * %s\n", headerstr[i]);
  1222. X    fputs(" */\n\n", xdrfile);
  1223. X    fprintf(xdrfile, "#include \"%s\"\n\n", inclfilename);
  1224. X    xdrflag = 1;
  1225. X    /* create routines for structure and type definitions used as process
  1226. X     * parameter, transaction parameter or transaction result types
  1227. X     */
  1228. X    if (first_structtype) {
  1229. X    for(stlptr = first_structtype; stlptr; stlptr = stlptr->next) {
  1230. X
  1231. X        switch(stlptr->symbol->type) {
  1232. X
  1233. X        case TYPEDEFNAME:
  1234. X        if (!stlptr->symbol->info.typedefname.BuildXDRRoutine)
  1235. X            continue;
  1236. X
  1237. X        stlptr->symbol->info.typedefname.BuildXDRRoutine = FALSE;
  1238. X
  1239. X                fprintf(xdrfile, "\nbool_t\n");
  1240. X                fprintf(xdrfile, "xdr_%s(xdrs, objp)\n", stlptr->symbol->name);
  1241. X                fprintf(xdrfile, "XDR *xdrs;\n%s *objp;\n{\n",
  1242. X            stlptr->symbol->name);
  1243. X
  1244. X        ds_attr = stlptr->symbol->info.typedefname.decl_spec;
  1245. X        if (ds_attr->ts || ds_attr->tq || 
  1246. X               (ds_attr->scs && ds_attr->scs->type != SCS_ATTR_TYPEDEF))
  1247. X            Panic("no \"typedef\" in type definition");
  1248. X        if (!ds_attr->ds) {
  1249. X            Errno = EILLTYPEDEF;
  1250. X                strcpy(yytext, stlptr->symbol->name);
  1251. X                Error(stlptr->symbol->info.typedefname.ErrPos, "");        
  1252. X            continue;
  1253. X        }
  1254. X
  1255. X        if (determine_typedef_xdr_routine(ds_attr->ds, &xdr_name, &type)) {
  1256. X                strcpy(yytext, stlptr->symbol->name);
  1257. X                Error(stlptr->symbol->info.typedefname.ErrPos, "");        
  1258. X            continue;
  1259. X        }
  1260. X    
  1261. X        if (stlptr->symbol->info.typedefname.IsPointer) {
  1262. X            if (determine_dcc_buf_size && !encode_warning)
  1263. X            print_dcc_buf_size_warning();
  1264. X            fprintf(xdrfile, "if (!xdr_pointer(xdrs, (char **) objp, sizeof(%s), xdr_%s", 
  1265. X            type, xdr_name);
  1266. X        } else 
  1267. X                    fprintf(xdrfile, "if (!xdr_%s(xdrs, objp", xdr_name);
  1268. X                fprintf(xdrfile, ")) {\nreturn (FALSE);\n}\n");
  1269. X        break;
  1270. X
  1271. X        case STRUCTDECL:
  1272. X        if (!stlptr->symbol->info.structdecl.BuildXDRRoutine)
  1273. X            continue;
  1274. X
  1275. X        stlptr->symbol->info.structdecl.BuildXDRRoutine = FALSE;
  1276. X
  1277. X                fprintf(xdrfile, "\nbool_t\n");
  1278. X                fprintf(xdrfile, "xdr_%s(xdrs, objp)\n", stlptr->symbol->name);
  1279. X                fprintf(xdrfile, "XDR *xdrs;\nstruct %s *objp;\n{\n",
  1280. X            stlptr->symbol->name);
  1281. X
  1282. X        /* for each struct_declaration do */
  1283. X        for(stl_attr = stlptr->symbol->info.structdecl.StruDeclList;
  1284. X                       stl_attr; stl_attr = stl_attr->st_list) {
  1285. X
  1286. X            /* get pointer to struct_declaration */
  1287. X            st_attr = stl_attr->struct_decl;
  1288. X
  1289. X            /* determine xdr routine and check for error */
  1290. X            if (determine_xdr_routine(st_attr->spec_qual_list, &xdr_name, &type)) {
  1291. X                strcpy(yytext, stlptr->symbol->name);
  1292. X                Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1293. X            continue;
  1294. X            }
  1295. X
  1296. X            /* for each struct_declarator do */
  1297. X            for(sdl_attr = st_attr->struct_decl_list; sdl_attr;
  1298. X                         sdl_attr = sdl_attr->sd_list) {
  1299. X
  1300. X            /* get pointer to struct_declarator */
  1301. X            sd_attr = sdl_attr->struct_declarator;
  1302. X
  1303. X            /* bitfields are not allowed */
  1304. X            if (sd_attr->const_expr) {
  1305. X                Errno = EILLBITFIELD;
  1306. X                    strcpy(yytext, stlptr->symbol->name);
  1307. X                    Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1308. X                continue;
  1309. X            }
  1310. X
  1311. X            /* get pointer to declarator */
  1312. X            d_attr = sd_attr->decl;
  1313. X
  1314. X            pointer_flag = FALSE;
  1315. X            /* only one pointer without type_qualifier is allowed */
  1316. X            if (d_attr->pointer) {
  1317. X                switch(d_attr->pointer->type) {
  1318. X                case P_ATTR_2:
  1319. X                    pointer_flag = TRUE;
  1320. X                break;
  1321. X                case P_ATTR_1:
  1322. X                case P_ATTR_3:
  1323. X                    Errno = EILLPOINTQUAL;
  1324. X                        strcpy(yytext, stlptr->symbol->name);
  1325. X                        Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1326. X                continue;
  1327. X
  1328. X                case P_ATTR_4:
  1329. X                    Errno = EMANYPOINTER;
  1330. X                        strcpy(yytext, stlptr->symbol->name);
  1331. X                        Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1332. X                continue;
  1333. X                default:
  1334. X                Panic("illegal P_ATTR type");
  1335. X                } /* switch */
  1336. X            }
  1337. X
  1338. X            /* get pointer to direct_declarator */
  1339. X            dd_attr = d_attr->direct_decl;
  1340. X
  1341. X            switch(dd_attr->type) {
  1342. X            case DD_ATTR_IDENT:
  1343. X                if (pointer_flag) {
  1344. X                    if (determine_dcc_buf_size && !encode_warning)
  1345. X                    print_dcc_buf_size_warning();
  1346. X                    fprintf(xdrfile, "if (!xdr_pointer(xdrs, (char **) &objp->%s, sizeof(%s), xdr_%s",
  1347. X                    dd_attr->ident->name, type, xdr_name);
  1348. X                } else {
  1349. X                    fprintf(xdrfile, "if (!xdr_%s(xdrs, &objp->%s",
  1350. X                    xdr_name, dd_attr->ident->name);
  1351. X                }
  1352. X                        fprintf(xdrfile, ")) {\nreturn (FALSE);\n}\n");
  1353. X                break;
  1354. X            case DD_ATTR_BRACED:
  1355. X                Errno = EILLBRACES;
  1356. X                    strcpy(yytext, stlptr->symbol->name);
  1357. X                    Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1358. X                continue;
  1359. X                /* break; */
  1360. X            case DD_ATTR_FUNC:
  1361. X                Errno = EILLFUNCTION;
  1362. X                    strcpy(yytext, stlptr->symbol->name);
  1363. X                    Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1364. X                continue;
  1365. X                /* break; */
  1366. X            case DD_ATTR_ARRAY:
  1367. X                if (pointer_flag) {
  1368. X                    Errno = EILLPOINTER;
  1369. X                        strcpy(yytext, stlptr->symbol->name);
  1370. X                        Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1371. X                    continue;
  1372. X                }
  1373. X                if (!dd_attr->info.comp.spec_str) {
  1374. X                    Errno = EARRAYSIZE;
  1375. X                        strcpy(yytext, stlptr->symbol->name);
  1376. X                        Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1377. X                    continue;
  1378. X                }
  1379. X                dd_attr2 = dd_attr->info.comp.direct_decl;
  1380. X                switch(dd_attr2->type) {
  1381. X                case DD_ATTR_IDENT:
  1382. X                fprintf(xdrfile, "if (!xdr_vector(xdrs, (char *) objp->%s, %s, sizeof(%s), xdr_%s)) {\n",
  1383. X                    dd_attr2->ident->name, dd_attr->info.comp.spec_str, 
  1384. X                    type, xdr_name);
  1385. X                            fprintf(xdrfile, "return (FALSE);\n}\n");
  1386. X                    break;
  1387. X                case DD_ATTR_BRACED:
  1388. X                    Errno = EILLARRBRACES;
  1389. X                        strcpy(yytext, stlptr->symbol->name);
  1390. X                        Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1391. X                    continue;
  1392. X                    /* break; */
  1393. X                case DD_ATTR_FUNC:
  1394. X                    Errno = EILLARRFUNCT;
  1395. X                        strcpy(yytext, stlptr->symbol->name);
  1396. X                        Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1397. X                    continue;
  1398. X                    /* break; */
  1399. X                case DD_ATTR_ARRAY:
  1400. X                Errno = EMULTIARRAY;
  1401. X                        strcpy(yytext, stlptr->symbol->name);
  1402. X                        Error(stlptr->symbol->info.structdecl.ErrPos, "");
  1403. X                    continue;
  1404. X                /* break; */
  1405. X                    default:
  1406. X                Panic("nor TYPEDEFNAME nor STRUCTDECL in struct_type_list");
  1407. X                    } /* switch(dd_attr2->type) */
  1408. X                continue;
  1409. X                /* break; */
  1410. X            } /* switch(dd_attr->type) */
  1411. X            } /* for(sdl_attr) */
  1412. X        } /* for(stl_attr) */
  1413. X        break;
  1414. X        default:
  1415. X        Panic("nor TYPEDEFNAME nor STRUCTDECL in struct_type_list");
  1416. X        } /* switch(stlptr->symbol->type) */
  1417. X            fprintf(xdrfile, "return (TRUE);\n}\n");
  1418. X        xdrextstr = Strcatmany(xdrextstr, 3, 
  1419. X            "extern bool_t xdr_", stlptr->symbol->name, "();\n");
  1420. X    } /* for(stlptr) */
  1421. X    }
  1422. X    
  1423. X    /* create routines for process parameters, transaction parameters and
  1424. X     * transaction results
  1425. X     */
  1426. X    for(sptr = symbtab.PstTab[0]; sptr; sptr = sptr->PstNext) {
  1427. X        if (sptr->type != PROCESSDECL)
  1428. X            continue;
  1429. X
  1430. X        if (sptr->info.process.FirstParam || sptr->info.process.FirstTrans)
  1431. X            fprintf(xdrfile, "\n/*\n * process '%s'\n */\n", sptr->name);
  1432. X
  1433. X    /* process parameters */
  1434. X        if (sptr->info.process.FirstParam) {
  1435. X            fprintf(xdrfile, "\nbool_t\n");
  1436. X            fprintf(xdrfile, "xdr_%s%s(xdrs, objp)\n", 
  1437. X        sptr->info.process.upiname, POSTFIXSPECPAR);
  1438. X            fprintf(xdrfile, "XDR *xdrs;\n%s%s *objp;\n{\n",
  1439. X        sptr->info.process.upiname, POSTFIXSPECPAR);
  1440. X            for(params = sptr->info.process.FirstParam; params;
  1441. X                                     params = params->info.varorpar.NextParam) {
  1442. X        ds_attr2 = params->info.varorpar.DataType;
  1443. X        if (ds_attr2->ts && ds_attr2->ts->type == TS_ATTR_STRUCT)
  1444. X            hstr = ds_attr2->ts->info.structinfo->tag->name;
  1445. X        else {
  1446. X                    *convert_buffer = 0;
  1447. X                    hstr = convert_buffer = convert_ds_to_string(convert_buffer, ds_attr2);
  1448. X        }
  1449. X                fprintf(xdrfile, "if (!xdr_%s(xdrs, &objp->%s)) {\n", hstr, params->name);
  1450. X                fprintf(xdrfile, "return (FALSE);\n}\n");
  1451. X            } /* for(params) */
  1452. X            fprintf(xdrfile, "return (TRUE);\n}\n");
  1453. X        xdrextstr = Strcatmany(xdrextstr, 4, 
  1454. X        "extern bool_t xdr_", 
  1455. X        sptr->info.process.upiname, 
  1456. X        POSTFIXSPECPAR, 
  1457. X        "();\n");
  1458. X        }
  1459. X
  1460. X    /* process transactions */
  1461. X        for(actions = sptr->info.process.FirstTrans; actions;
  1462. X                                      actions = actions->info.trans.NextTrans) {
  1463. X
  1464. X        /* transaction parameters */
  1465. X        if (actions->info.trans.FirstParam) {
  1466. X                fprintf(xdrfile, "\nbool_t\n");
  1467. X                fprintf(xdrfile, "xdr_%s%s(xdrs, objp)\n", 
  1468. X            actions->info.trans.uptiname, POSTFIXTRANSPAR);
  1469. X                fprintf(xdrfile, "XDR *xdrs;\n%s%s *objp;\n{\n",
  1470. X            actions->info.trans.uptiname, POSTFIXTRANSPAR);
  1471. X        for(params = actions->info.trans.FirstParam; params;
  1472. X                                     params = params->info.varorpar.NextParam) {
  1473. X            ds_attr2 = params->info.varorpar.DataType;
  1474. X            if (ds_attr2->ts && ds_attr2->ts->type == TS_ATTR_STRUCT)
  1475. X                        hstr = ds_attr2->ts->info.structinfo->tag->name;
  1476. X                    else {
  1477. X                        *convert_buffer = 0;
  1478. X                        hstr = convert_buffer = convert_ds_to_string(convert_buffer, 
  1479. X                        ds_attr2);
  1480. X            }
  1481. X                    fprintf(xdrfile, "if (!xdr_%s(xdrs, &objp->%s)) {\n", 
  1482. X                hstr, params->name);
  1483. X                    fprintf(xdrfile, "return (FALSE);\n}\n");
  1484. X                } /* for(params) */
  1485. X                fprintf(xdrfile, "return (TRUE);\n}\n");
  1486. X            xdrextstr = Strcatmany(xdrextstr, 4, 
  1487. X            "extern bool_t xdr_", 
  1488. X            actions->info.trans.uptiname, 
  1489. X            POSTFIXTRANSPAR, 
  1490. X            "();\n");
  1491. X        }
  1492. X
  1493. X        /* transaction result */
  1494. X            fprintf(xdrfile, "\nbool_t\n");
  1495. X            fprintf(xdrfile, "xdr_%s%s(xdrs, objp)\n", 
  1496. X        actions->info.trans.uptiname, POSTFIXTRANSRES);
  1497. X            fprintf(xdrfile, "XDR *xdrs;\n%s%s *objp;\n{\n",
  1498. X        actions->info.trans.uptiname, POSTFIXTRANSRES);
  1499. X        ds_attr2 = actions->info.trans.ReturnType;
  1500. X        if (ds_attr2->ts && ds_attr2->ts->type == TS_ATTR_STRUCT)
  1501. X                hstr = ds_attr2->ts->info.structinfo->tag->name;
  1502. X        else {
  1503. X                *convert_buffer = 0;
  1504. X                hstr = convert_buffer = convert_ds_to_string(convert_buffer, ds_attr2);
  1505. X        }
  1506. X            fprintf(xdrfile, "if (!xdr_%s(xdrs, &objp->result)) {\n", hstr);
  1507. X            fprintf(xdrfile, "return (FALSE);\n}\n");
  1508. X            fprintf(xdrfile, "if (!xdr_int(xdrs, &objp->Errno)) {\n");
  1509. X            fprintf(xdrfile, "return (FALSE);\n}\n");
  1510. X            fprintf(xdrfile, "if (!xdr_int(xdrs, &objp->errno)) {\n");
  1511. X            fprintf(xdrfile, "return (FALSE);\n}\n");
  1512. X            fprintf(xdrfile, "return (TRUE);\n}\n");
  1513. X        xdrextstr = Strcatmany(xdrextstr, 4, 
  1514. X        "extern bool_t xdr_", 
  1515. X        actions->info.trans.uptiname, 
  1516. X        POSTFIXTRANSRES,
  1517. X        "();\n");
  1518. X
  1519. X        } /* for(actions) */
  1520. X
  1521. X    } /* for(sptr) */
  1522. X
  1523. X    return(OK);
  1524. X} /* build_xdrfile */
  1525. X
  1526. X#endif /* HETEROGENEOUS /**/
  1527. END_OF_FILE
  1528. if test 26041 -ne `wc -c <'dcc/xdrfile.c'`; then
  1529.     echo shar: \"'dcc/xdrfile.c'\" unpacked with wrong size!
  1530. fi
  1531. # end of 'dcc/xdrfile.c'
  1532. fi
  1533. echo shar: End of archive 14 \(of 18\).
  1534. cp /dev/null ark14isdone
  1535. MISSING=""
  1536. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  1537.     if test ! -f ark${I}isdone ; then
  1538.     MISSING="${MISSING} ${I}"
  1539.     fi
  1540. done
  1541. if test "${MISSING}" = "" ; then
  1542.     echo You have unpacked all 18 archives.
  1543.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1544. else
  1545.     echo You still need to unpack the following archives:
  1546.     echo "        " ${MISSING}
  1547. fi
  1548. ##  End of shell archive.
  1549. exit 0
  1550.