home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / distributed-c-2.1 / part16 < prev    next >
Text File  |  1993-12-22  |  89KB  |  2,815 lines

  1. Newsgroups: comp.sources.unix
  2. From: pleierc@informatik.tu-muenchen.de (Christoph Pleier)
  3. Subject: v27i190: distributed-c-2.1 - Distributed C Development Environment, V2.1, Part16/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 190
  10. Archive-Name: distributed-c-2.1/part16
  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 16 (of 18)."
  19. # Contents:  dcc/dcc.y lib/ipc_msgsem.c
  20. # Wrapped by vixie@gw.home.vix.com on Thu Dec 23 00:12:06 1993
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. if test -f 'dcc/dcc.y' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'dcc/dcc.y'\"
  24. else
  25. echo shar: Extracting \"'dcc/dcc.y'\" \(42425 characters\)
  26. sed "s/^X//" >'dcc/dcc.y' <<'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 *                                d c c . y                                *
  38. X *                                                                         *
  39. X *                            Package : Compiler                           *
  40. X *                            Version : 1.4                                *
  41. X *                       CreationDate : 05.07.90                           *
  42. X *                         LastUpDate : 18.10.93                           *
  43. X *                                                                         *
  44. X *                  The YACC - grammar for Distributed C.                  *
  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%{
  62. X#include <stdio.h>
  63. X#include <string.h>
  64. X#include "config.h"
  65. X#include "extern.h"
  66. X#include "functions.h"
  67. X#include "com_Errno.h"
  68. X
  69. X#define DECERRFLAG    if (errflag) \
  70. X                --errflag
  71. X%}
  72. X
  73. X/*
  74. X * the type of the value stack
  75. X */
  76. X
  77. X%union {
  78. X    int         y_int;    /* an integer value                      */
  79. X    SYMBTABEL  *y_symb;    /* a symbol table entry                  */
  80. X    char       *y_str;    /* a string                              */
  81. X    ARG_LIST   *y_arg;     /* an argument expression list           */
  82. X    POSTATTR   *y_post;    /* a postfix expression attribute        */
  83. X    COMPATTR   *y_comp;    /* a compound statement attribute        */
  84. X    ACCEPTATTR *y_accept;    /* an accept statement attribute         */
  85. X    SELECTATTR *y_select;    /* a select statement attribute          */
  86. X    TRANSATTR  *y_trans;    /* a transaction_call attribute          */
  87. X    DS_ATTR    *y_ds;    /* a declaration specifiers attribute    */
  88. X    SUS_ATTR   *y_sus;    /* a struct or union specifier attribute */
  89. X    SCS_ATTR   *y_scs;    /* a storage class specifier attribute   */
  90. X    TS_ATTR    *y_ts;    /* a type specifier attribute            */
  91. X    TQ_ATTR    *y_tq;    /* a type qualifier attribute            */
  92. X    SU_ATTR    *y_su;    /* a struct or union attribute           */
  93. X    SD_ATTR    *y_sd;    /* a struct declarator attribute         */
  94. X    ST_ATTR    *y_st;    /* a struct declaration attribute        */
  95. X    SQL_ATTR   *y_sql;    /* a specifier qualifier list attribute  */
  96. X    SDL_ATTR   *y_sdl;    /* a struct declarator list attribute    */
  97. X    STL_ATTR   *y_stl;    /* a struct declaration list attribute   */
  98. X    TQL_ATTR   *y_tql;    /* a type qualifier list attribute       */
  99. X    D_ATTR     *y_d;    /* a declarator attribute                */
  100. X    DD_ATTR    *y_dd;    /* a direct declarator attribute         */
  101. X    P_ATTR     *y_p;    /* a pointer attribute                   */
  102. X    ES_ATTR    *y_es;    /* a enum specifier attribute            */
  103. X    ID_ATTR    *y_id;    /* a init declarator attribute           */
  104. X    IDL_ATTR   *y_idl;    /* a init declarator list attribute      */
  105. X}
  106. X
  107. X/* 
  108. X * characters 
  109. X */
  110. X
  111. X%token ',' ';' ':' '.' '+' '-' '*' '/' '%' '~' '!' '&' '|' '^'
  112. X%token '=' '<' '>' '{' '}' '[' ']' '(' ')' '\"' '\'' '\\' '@'
  113. X
  114. X/*
  115. X * special characters
  116. X */
  117. X
  118. X%token ARROW EEQUAL GE LE LOGAND LOGOR LSHIFT RSHIFT NOTEQUAL TREEPOINT
  119. X%token AMPERS_ASSIGN MUL_ASSIGN DIV_ASSIGN HAT_ASSIGN MOD_ASSIGN 
  120. X%token LSHIFT_ASSIGN RSHIFT_ASSIGN PIPE_ASSIGN PLUS_ASSIGN MINUS_ASSIGN
  121. X%token MINUSMINUS PLUSPLUS  
  122. X%token ENDOFINPUT
  123. X
  124. X/* 
  125. X * reserved words 
  126. X */
  127. X
  128. X%token AT ACCEPT AUTO BODY BREAK CASE CHAR CONST CONTINUE CREATE DEFAULT
  129. X%token DESTROY DO DOUBLE ELSE ENUM EXTERN FLOAT FOR GOTO HOST IF INT LOCAL 
  130. X%token LONG OR PROCESS REGISTER RETURN SELECT SHORT SIGNED SIZEOF SPEC STATIC
  131. X%token STRUCT SWITCH TERMINATE TRANS TRETURN TYPEDEF UNION UNSIGNED VOID
  132. X%token VOLATILE WHILE WITHIN
  133. X
  134. X/* 
  135. X * special terminals 
  136. X */
  137. X
  138. X%token          CHR_CONST INT_CONST FLOAT_CONST STR_CONST
  139. X%token <y_str>  ENUMCONST
  140. X%token <y_symb> IDENT TYPEDEF_NAME
  141. X
  142. X/* 
  143. X * nonterminal types 
  144. X */
  145. X
  146. X%type <y_str>    translation_unit external_declaration function_definition
  147. X%type <y_str>    declaration declaration_list enumerator_list enumerator 
  148. X%type <y_str>    parameter_type_list parameter_list parameter_declaration 
  149. X%type <y_str>    identifier_list initializer initializer_list type_name 
  150. X%type <y_str>    abstract_declarator direct_abstract_declarator 
  151. X%type <y_str>    logical_OR_expression statement labeled_statement 
  152. X%type <y_str>    expression_statement statement_list selection_statement 
  153. X%type <y_str>    iteration_statement jump_statement select_statement
  154. X%type <y_str>    expression assignment_expression assignment_operator
  155. X%type <y_str>    conditional_expression constant_expression 
  156. X%type <y_str>    logical_AND_expression  inclusive_OR_expression 
  157. X%type <y_str>    exclusive_OR_expression AND_expression equality_expression
  158. X%type <y_str>    relational_expression shift_expression additive_expression
  159. X%type <y_str>    multiplicative_expression cast_expression unary_expression
  160. X%type <y_str>    unary_operator process_creation parameterleiste
  161. X%type <y_str>    primary_expression argument_expression_list constant
  162. X%type <y_str>    process_location opt_identifier_list destroy_statement
  163. X%type <y_str>    process_definition immediate_alternative
  164. X%type <y_str>    timed_transaction_call 
  165. X%type <y_symb>   process_parameter_list process_specification process_parameters
  166. X%type <y_symb>   process_transactions transaction_declaration 
  167. X%type <y_symb>   transaction_declaration_list
  168. X%type <y_arg>    process_arguments process_arg_expr_list 
  169. X%type <y_comp>   compound_statement 
  170. X%type <y_accept> accept_statement 
  171. X%type <y_select> select_list select_part alternative accept_alternative
  172. X%type <y_select> terminate_alternative 
  173. X%type <y_post>   postfix_expression 
  174. X%type <y_trans>  transaction_call 
  175. X
  176. X%type <y_ds>     declaration_specifiers 
  177. X%type <y_scs>    storage_class_specifier 
  178. X%type <y_ts>     type_specifier
  179. X%type <y_tq>     type_qualifier
  180. X%type <y_sus>    struct_or_union_specifier
  181. X%type <y_stl>    struct_declaration_list
  182. X%type <y_st>     struct_declaration 
  183. X%type <y_sql>    specifier_qualifier_list 
  184. X%type <y_sdl>    struct_declarator_list 
  185. X%type <y_sd>     struct_declarator 
  186. X%type <y_d>      declarator 
  187. X%type <y_dd>     direct_declarator
  188. X%type <y_su>     struct_or_union
  189. X%type <y_p>      pointer
  190. X%type <y_tql>    type_qualifier_list
  191. X%type <y_es>     enum_specifier
  192. X%type <y_id>     init_declarator
  193. X%type <y_idl>    init_declarator_list 
  194. X
  195. X/*
  196. X * the start token
  197. X */
  198. X
  199. X%start program
  200. X
  201. X%%
  202. X
  203. X/*
  204. X * the grammar syntax and actions 
  205. X */
  206. X
  207. Xprogram:
  208. X        {(void) init_symbtab();}
  209. X      translation_unit
  210. X        {/* KEEP THIS ORDER OF FUNCTION CALLS!!! */
  211. X#if defined(HETEROGENEOUS) || defined(CHECK_XDR)
  212. X         (void) build_xdrfile();
  213. X#endif /* HETEROGENEOUS /**/
  214. X         (void) build_includefile();
  215. X         (void) build_makefile();
  216. X         if (mainflag)
  217. X             fputs($2, outfile);
  218. X         /* (void) display_symbol_table(); */
  219. X        }
  220. X    ;
  221. X
  222. Xtranslation_unit:
  223. X      external_declaration
  224. X    | translation_unit external_declaration
  225. X        {$$ = Strcat($1, $2);
  226. X         Free($2);
  227. X        }
  228. X    ;
  229. X
  230. Xexternal_declaration:
  231. X      function_definition
  232. X    | process_specification
  233. X        {$$ = strmalloc("\n");}
  234. X    | process_definition
  235. X    | declaration
  236. X    ;
  237. X
  238. Xfunction_definition:
  239. X      declaration_specifiers declarator 
  240. X        {(void) make_function($1, $2);
  241. X         blk_push();
  242. X        }
  243. X    declaration_list compound_statement
  244. X        {$$ = gencode_function($1, $2, $4, $5);
  245. X         Free((char *) $2);
  246. X         Free($4);
  247. X         Free((char *) $5);
  248. X         blk_pop();
  249. X        }
  250. X    | declarator 
  251. X                {(void) make_function(NULL, $1);
  252. X                 blk_push();
  253. X                }
  254. X      declaration_list compound_statement
  255. X        {$$ = gencode_function(NULL, $1, $3, $4);
  256. X         Free((char *) $1);
  257. X         Free((char *) $4);
  258. X                 blk_pop();
  259. X        }
  260. X    | declaration_specifiers declarator 
  261. X                {(void) make_function($1, $2);
  262. X                 blk_push();
  263. X                }
  264. X      compound_statement
  265. X        {$$ = gencode_function($1, $2, "", $4);
  266. X         Free((char *) $2);
  267. X         Free((char *) $4);
  268. X         blk_pop();
  269. X        }
  270. X    | declarator 
  271. X                {(void) make_function(NULL, $1);
  272. X                 blk_push();
  273. X                }
  274. X      compound_statement
  275. X        {$$ = gencode_function(NULL, $1, "", $3);
  276. X         Free((char *) $1);
  277. X         /* Free((char *) $3->stats); */
  278. X                 blk_pop();
  279. X        }
  280. X    ;
  281. X
  282. Xprocess_specification:
  283. X      PROCESS SPEC IDENT 
  284. X        {$$ = make_process($3);
  285. X         blk_push(); 
  286. X        }
  287. X      process_parameters process_transactions
  288. X        {DECERRFLAG;
  289. X         blk_pop();
  290. X         (void) add_process_info($3, $5, $6); 
  291. X         (void) add_trans_info($3, $6);
  292. X        }
  293. X    | PROCESS SPEC error 
  294. X        {yynerrs--;
  295. X         Errno = EINPROCSPEC;
  296. X         Error(NULL, "");
  297. X        }
  298. X      IDENT process_parameters process_transactions
  299. X        {$$ = make_process($6);}
  300. X    ;
  301. X
  302. Xprocess_parameters:
  303. X      '(' ')'
  304. X        {$$ = (SYMBTABEL *) NULL;}
  305. X    | '(' process_parameter_list ')'
  306. X        {$$ = $2;}
  307. X    | error
  308. X        {yynerrs--;
  309. X         Errno = EPROCPAREXP;
  310. X         Error(NULL, "");
  311. X         $$ = (SYMBTABEL *) NULL;
  312. X        }
  313. X    | error 
  314. X        {yynerrs--;
  315. X         Errno = EPROCPAREXP2;
  316. X         Error(NULL, "");
  317. X        }
  318. X      '(' process_parameter_list ')'
  319. X        {$$ = (SYMBTABEL *) NULL;}
  320. X    ;
  321. X
  322. Xprocess_parameter_list:
  323. X      declaration_specifiers IDENT 
  324. X        {$$ = add_parm_type(mark_struct_or_type_def_for_XDR($1), make_parameter($2));}
  325. X    | declaration_specifiers IDENT ',' process_parameter_list 
  326. X        {$$ = link_parameters(add_parm_type(mark_struct_or_type_def_for_XDR($1), make_parameter($2)), $4);}
  327. X    | error
  328. X        {yynerrs--;
  329. X         Errno = EINPROCPARAM;
  330. X         Error(NULL, "");
  331. X         $$ = (SYMBTABEL *) NULL;
  332. X        }
  333. X    | declaration_specifiers error
  334. X        {yynerrs--;
  335. X         Errno = EINPROCPARAM;
  336. X         Error(NULL, "");
  337. X         $$ = (SYMBTABEL *) NULL;
  338. X        }
  339. X    | declaration_specifiers IDENT error 
  340. X        {yynerrs--;
  341. X         Errno = EINPROCPARAM;
  342. X         Error(NULL, "");
  343. X         $$ = (SYMBTABEL *) NULL;
  344. X        }
  345. X    | declaration_specifiers IDENT error 
  346. X        {yynerrs--;
  347. X         Errno = EINPROCPARAM;
  348. X         Error(NULL, "");
  349. X        }
  350. X      process_parameter_list
  351. X        {$$ = (SYMBTABEL *) NULL;}
  352. X    | error 
  353. X        {yynerrs--;
  354. X         Errno = EINPROCPARAM;
  355. X         Error(NULL, "");
  356. X        }
  357. X      ',' process_parameter_list
  358. X        {$$ = (SYMBTABEL *) NULL;}
  359. X    | error 
  360. X        {yynerrs--;
  361. X         Errno = EINPROCPARAM;
  362. X         Error(NULL, "");
  363. X        }
  364. X      process_parameter_list
  365. X        {$$ = (SYMBTABEL *) NULL;}
  366. X    ;
  367. X
  368. Xprocess_transactions:
  369. X      ';'
  370. X        {$$ = (SYMBTABEL *) NULL;}
  371. X    | '{' transaction_declaration_list '}' 
  372. X        {$$ = $2;}
  373. X    | error 
  374. X        {yynerrs--;
  375. X         Errno = EPROCTRANSEXP;
  376. X         Error(NULL, "");
  377. X        }
  378. X      ';'
  379. X        {yyerrok;
  380. X         $$ = (SYMBTABEL *) NULL;
  381. X        }
  382. X    | error 
  383. X        {yynerrs--;
  384. X         Errno = EPROCTRANSEXP2;
  385. X         Error(NULL, "");
  386. X        }
  387. X      '{' transaction_declaration_list '}' 
  388. X        {$$ = $4;}
  389. X    ;
  390. X
  391. Xtransaction_declaration_list:
  392. X      transaction_declaration
  393. X    | transaction_declaration_list transaction_declaration
  394. X        {$$ = link_transactions($1, $2);}
  395. X    ;
  396. X
  397. Xtransaction_declaration:
  398. X      TRANS declaration_specifiers IDENT 
  399. X        {(void) mark_struct_or_type_def_for_XDR($2);
  400. X         $$ = make_transaction($3);
  401. X         blk_push();
  402. X        }
  403. X      process_parameters ';'
  404. X        {blk_pop();
  405. X         $$ = add_transaction_info($3, $2, $5); 
  406. X        }
  407. X    | TRANS error 
  408. X        {yynerrs--;
  409. X         Errno = EINTRANSDECL;
  410. X         Error(NULL, "");
  411. X        }
  412. X      ';'
  413. X        {yyerrok;
  414. X         $$ = (SYMBTABEL *) NULL;
  415. X        }
  416. X    | TRANS error 
  417. X        {yynerrs--;
  418. X         Errno = EINTRANSDECL2;
  419. X         Error(NULL, "");
  420. X        }
  421. X      IDENT process_parameters ';'
  422. X        {yyerrok;
  423. X         $$ = make_transaction($4);
  424. X        }
  425. X    | TRANS declaration_specifiers error 
  426. X        {yynerrs--;
  427. X         Errno = EINTRANSDECL3;
  428. X         Error(NULL, "");
  429. X        }
  430. X      IDENT process_parameters ';'
  431. X        {yyerrok;
  432. X         $$ = make_transaction($5);
  433. X        }
  434. X    ;
  435. X
  436. Xprocess_definition:
  437. X      PROCESS BODY IDENT 
  438. X        {(void) make_process_def($3);
  439. X         (void) gen_process_creation_routine($3);
  440. X         (void) gen_call_transaction_routines($3);
  441. X         bodyflag = TRUE;
  442. X         blk_push();
  443. X         (void) reenter_process_comps($3);
  444. X        }
  445. X      '(' opt_identifier_list ')'
  446. X        {(void) gen_process_file($3);}
  447. X      compound_statement 
  448. X        {(void) gencode_process_body($3, $9);
  449. X         $$ = strmalloc("");
  450. X         bodyflag = FALSE; 
  451. X         blk_pop();
  452. X        }
  453. X    | PROCESS BODY error 
  454. X        {yynerrs--;
  455. X         Errno = EINPROCDEF;
  456. X         Error(NULL, "");
  457. X        }
  458. X      IDENT '(' opt_identifier_list ')' compound_statement 
  459. X        {(void) make_process_def($5);
  460. X         $$ = strmalloc("");
  461. X        }
  462. X    ;
  463. X
  464. Xdeclaration:
  465. X      declaration_specifiers init_declarator_list ';'
  466. X        {$$ = evaluate_declaration($1, $2);
  467. X         DECERRFLAG;
  468. X                }
  469. X    | declaration_specifiers ';'
  470. X        {$$ = evaluate_declaration($1, NULL);
  471. X         DECERRFLAG;
  472. X        }
  473. X    ;
  474. X
  475. Xdeclaration_list:
  476. X      declaration
  477. X    | declaration_list declaration
  478. X        {$$ = Strcat($1, $2);
  479. X         Free($2);
  480. X        }
  481. X    | declaration_list error
  482. X    ;
  483. X
  484. Xdeclaration_specifiers:
  485. X      storage_class_specifier declaration_specifiers
  486. X        {$$ = gen_declaration_specifiers_attr($1, NULL, NULL, $2);}
  487. X    | storage_class_specifier
  488. X        {$$ = gen_declaration_specifiers_attr($1, NULL, NULL, NULL);}
  489. X    | type_specifier declaration_specifiers
  490. X        {$$ = gen_declaration_specifiers_attr(NULL, $1, NULL, $2);}
  491. X    | type_specifier 
  492. X        {$$ = gen_declaration_specifiers_attr(NULL, $1, NULL, NULL);}
  493. X    | type_qualifier declaration_specifiers
  494. X        {$$ = gen_declaration_specifiers_attr(NULL, NULL, $1, $2);}
  495. X    | type_qualifier 
  496. X        {$$ = gen_declaration_specifiers_attr(NULL, NULL, $1, NULL);}
  497. X    ;
  498. X
  499. Xstorage_class_specifier:
  500. X      AUTO
  501. X        {$$ = gen_storage_class_spec_attr(SCS_ATTR_AUTO);}
  502. X    | REGISTER
  503. X        {$$ = gen_storage_class_spec_attr(SCS_ATTR_REGISTER);}
  504. X    | STATIC
  505. X        {$$ = gen_storage_class_spec_attr(SCS_ATTR_STATIC);}
  506. X    | EXTERN
  507. X        {$$ = gen_storage_class_spec_attr(SCS_ATTR_EXTERN);}
  508. X    | TYPEDEF
  509. X        {$$ = gen_storage_class_spec_attr(SCS_ATTR_TYPEDEF);}
  510. X    ;
  511. X
  512. Xtype_specifier:    
  513. X      VOID
  514. X        {$$ = gen_type_specifier_attr(TS_ATTR_VOID, NULL, NULL, NULL);}
  515. X    | CHAR
  516. X        {$$ = gen_type_specifier_attr(TS_ATTR_CHAR, NULL, NULL, NULL);}
  517. X    | SHORT
  518. X        {$$ = gen_type_specifier_attr(TS_ATTR_SHORT, NULL, NULL, NULL);}
  519. X    | INT
  520. X        {$$ = gen_type_specifier_attr(TS_ATTR_INT, NULL, NULL, NULL);}
  521. X    | LONG
  522. X        {$$ = gen_type_specifier_attr(TS_ATTR_LONG, NULL, NULL, NULL);}
  523. X    | FLOAT
  524. X        {$$ = gen_type_specifier_attr(TS_ATTR_FLOAT, NULL, NULL, NULL);}
  525. X    | DOUBLE
  526. X        {$$ = gen_type_specifier_attr(TS_ATTR_DOUBLE, NULL, NULL, NULL);}
  527. X    | PROCESS IDENT
  528. X        {(void) is_process($2); 
  529. X         processptr = $2;
  530. X         $$ = gen_type_specifier_attr(TS_ATTR_PROCESS, NULL, NULL, $2);
  531. X        }
  532. X    | SIGNED
  533. X        {$$ = gen_type_specifier_attr(TS_ATTR_SIGNED, NULL, NULL, NULL);}
  534. X     | UNSIGNED
  535. X        {$$ = gen_type_specifier_attr(TS_ATTR_UNSIGNED, NULL, NULL, NULL);}
  536. X    | enum_specifier
  537. X        {$$ = gen_type_specifier_attr(TS_ATTR_ENUM, $1, NULL, NULL);}
  538. X    | struct_or_union_specifier
  539. X        {$$ = gen_type_specifier_attr(TS_ATTR_STRUCT, NULL, $1, NULL);}
  540. X    | TYPEDEF_NAME /* IDENT */
  541. X        {$$ = gen_type_specifier_attr(TS_ATTR_TYPENAME, NULL, NULL, $1);}
  542. X    ;
  543. X
  544. Xtype_qualifier:
  545. X      CONST
  546. X        {$$ = gen_type_qualifier_attr(TQ_ATTR_CONST);}
  547. X    | VOLATILE
  548. X        {$$ = gen_type_qualifier_attr(TQ_ATTR_VOLATILE);}
  549. X    ;
  550. X
  551. Xstruct_or_union_specifier:
  552. X      struct_or_union IDENT 
  553. X        {blk_push();}
  554. X      '{' struct_declaration_list '}'
  555. X        {blk_pop();
  556. X         (void) make_structure($2);
  557. X         (void) add_struct_or_union_info($1, $2, $5);
  558. X         $$ = gen_struct_or_union_spec_attr($1, $2, $5);
  559. X        }
  560. X    | struct_or_union 
  561. X        {blk_push();}
  562. X      '{' struct_declaration_list '}'
  563. X        {blk_pop();
  564. X         $$ = gen_struct_or_union_spec_attr($1, NULL, $4);
  565. X        }
  566. X    | struct_or_union IDENT
  567. X        {$$ = gen_struct_or_union_spec_attr($1, $2, NULL);}
  568. X
  569. X    /* Typedef_names are not alled as structure tag names.
  570. X     * The next production is semantically not correct!
  571. X     * But to allow declarations which use the same identifier as
  572. X     * structure tag name and as subsequent type definition, e. g.
  573. X     * "typedef struct NAME { ... } NAME;", we made the following
  574. X     * hack.
  575. X     */
  576. X    | struct_or_union TYPEDEF_NAME
  577. X        {$$ = gen_struct_or_union_spec_attr($1, $2, NULL);}
  578. X
  579. X    | struct_or_union error IDENT '{' struct_declaration_list '}'
  580. X        {$$ = NULL;}
  581. X    | struct_or_union error '{' struct_declaration_list '}' error
  582. X        {$$ = NULL;}
  583. X    ;
  584. X
  585. Xstruct_or_union:
  586. X      STRUCT 
  587. X        {$$ = gen_struct_or_union_attr(SU_ATTR_STRUCT);}
  588. X    | UNION
  589. X        {$$ = gen_struct_or_union_attr(SU_ATTR_UNION);}
  590. X    ;
  591. X
  592. Xstruct_declaration_list:
  593. X      struct_declaration
  594. X        {$$ = gen_stru_declaration_list_attr($1);}
  595. X    | struct_declaration_list struct_declaration
  596. X        {$$ = add_struct_declaration($1, gen_stru_declaration_list_attr($2));}
  597. X    | error
  598. X        {$$ = NULL;}
  599. X    | struct_declaration_list error
  600. X    ;
  601. X
  602. Xinit_declarator_list:    
  603. X      init_declarator
  604. X                {$$ = gen_init_declarator_list_attr($1);}
  605. X    | init_declarator_list ',' init_declarator
  606. X        {$$ = add_init_declarator_list($1, gen_init_declarator_list_attr($3));}
  607. X    | error
  608. X        {$$ = NULL;}
  609. X    | init_declarator_list error init_declarator
  610. X    | init_declarator_list ',' error
  611. X    ;
  612. X
  613. Xinit_declarator:
  614. X      declarator
  615. X        {$$ = gen_init_declarator_attr($1, NULL);}
  616. X    | declarator '=' initializer
  617. X        {$$ = gen_init_declarator_attr($1, $3);}
  618. X    | declarator '=' error 
  619. X        {$$ = gen_init_declarator_attr($1, NULL);}
  620. X    | error '=' initializer
  621. X        {$$ = NULL;}
  622. X    ;
  623. X
  624. Xstruct_declaration:
  625. X      specifier_qualifier_list struct_declarator_list ';'
  626. X        {$$ = gen_struct_declaration_attr($1, $2);
  627. X         DECERRFLAG;
  628. X        }
  629. X    | error ';'
  630. X        {yyerrok;
  631. X         $$ = NULL;
  632. X        }
  633. X    ;
  634. X
  635. Xspecifier_qualifier_list:
  636. X      type_specifier specifier_qualifier_list
  637. X        {$$ = add_spec_qual_list(gen_spec_qual_list_attr($1, NULL), $2);}
  638. X    | type_specifier
  639. X        {$$ = gen_spec_qual_list_attr($1, NULL);}
  640. X    | type_qualifier specifier_qualifier_list
  641. X        {$$ = add_spec_qual_list(gen_spec_qual_list_attr(NULL, $1), $2);}
  642. X    | type_qualifier
  643. X        {$$ = gen_spec_qual_list_attr(NULL, $1);}
  644. X    ;
  645. X
  646. Xstruct_declarator_list:
  647. X      struct_declarator
  648. X        {$$ = gen_struct_declarator_list_attr($1);}
  649. X    | struct_declarator_list ',' struct_declarator
  650. X        {$$ = add_struct_declarator($1, gen_struct_declarator_list_attr($3));}
  651. X    | error
  652. X        {$$ = NULL;}
  653. X    | struct_declarator_list error struct_declarator
  654. X    | struct_declarator_list ',' error
  655. X    ;
  656. X
  657. Xstruct_declarator:
  658. X      declarator
  659. X        {$$ = gen_struct_declarator_attr($1, NULL);}
  660. X    | declarator ':' constant_expression
  661. X        {$$ = gen_struct_declarator_attr($1, $3);}
  662. X    | ':' constant_expression
  663. X        {$$ = gen_struct_declarator_attr(NULL, $2);}
  664. X    | declarator ':' error constant_expression
  665. X        {$$ = NULL;}
  666. X    | ':' error constant_expression
  667. X        {$$ = NULL;}
  668. X    ;
  669. X
  670. Xenum_specifier:
  671. X      ENUM IDENT '{' enumerator_list '}'
  672. X        {$$ = gen_enum_specifier_attr(Strcatmany(strmalloc("enum "), 4,
  673. X            $2->name," { ",$4," } "));
  674. X         Free($4);
  675. X        }
  676. X    | ENUM '{' enumerator_list '}'
  677. X        {$$ = gen_enum_specifier_attr(Strcatmany(strmalloc("enum { "), 
  678. X            2, $3, " } "));
  679. X         Free($3);
  680. X        }
  681. X    | ENUM IDENT
  682. X        {$$ = gen_enum_specifier_attr(Strcat(strmalloc("enum "), $2->name));}
  683. X    | ENUM error
  684. X        {$$ = gen_enum_specifier_attr(strmalloc(""));}
  685. X    ;
  686. X
  687. Xenumerator_list:
  688. X      enumerator
  689. X    | enumerator_list ',' enumerator
  690. X        {$$ = Strcatmany($1, 2, ",", $3);
  691. X         Free($3);
  692. X        }
  693. X    ;
  694. X
  695. Xenumerator:
  696. X      IDENT
  697. X        {$$ = strmalloc($1->name);}
  698. X    | IDENT '=' constant_expression
  699. X        {$$ = Strcatmany(strmalloc($1->name), 2, " = ", $3);
  700. X         Free($3);
  701. X        }
  702. X    | error
  703. X        {$$ = strmalloc("");}
  704. X     | IDENT '=' error
  705. X        {$$ = strmalloc("");}
  706. X    | error constant_expression
  707. X        {$$ = $2;}
  708. X    | IDENT error
  709. X        {$$ = strmalloc("");}
  710. X    | IDENT error constant_expression
  711. X        {$$ = $3;}
  712. X    ;
  713. X
  714. Xdeclarator:
  715. X      pointer direct_declarator
  716. X        {$$ = gen_declarator_attr($1, $2);}
  717. X    | direct_declarator
  718. X        {$$ = gen_declarator_attr(NULL, $1);}
  719. X    | pointer error
  720. X        {$$ = NULL;}
  721. X    | pointer error direct_declarator
  722. X        {$$ = NULL;}
  723. X    ;
  724. X
  725. Xdirect_declarator:
  726. X      IDENT
  727. X        {$$ = gen_direct_decl_attr(DD_ATTR_IDENT, $1, NULL, NULL, NULL);}
  728. X    | '(' declarator ')'
  729. X        {$$ = gen_direct_decl_attr(DD_ATTR_BRACED, NULL, $2, NULL, NULL);}
  730. X    | direct_declarator '[' constant_expression ']'
  731. X        {$$ = gen_direct_decl_attr(DD_ATTR_ARRAY, NULL, NULL, $1, $3);}
  732. X    | direct_declarator '[' ']'
  733. X        {$$ = gen_direct_decl_attr(DD_ATTR_ARRAY, NULL, NULL, $1, NULL);}
  734. X    | direct_declarator '(' 
  735. X        {blk_push();}
  736. X      parameterleiste ')'
  737. X        {blk_pop();
  738. X         $$ = gen_direct_decl_attr(DD_ATTR_FUNC, NULL, NULL, $1, $4);
  739. X        }
  740. X    ;
  741. X
  742. Xparameterleiste:
  743. X      identifier_list
  744. X    | parameter_type_list
  745. X    | /* empty */
  746. X        {$$ = strmalloc("");}
  747. X    ;
  748. X
  749. Xpointer:
  750. X      '*' type_qualifier_list
  751. X        {$$ = gen_pointer_attr(P_ATTR_1, $2, NULL);}
  752. X    | '*' 
  753. X        {$$ = gen_pointer_attr(P_ATTR_2, NULL, NULL);}
  754. X    | '*' type_qualifier_list pointer
  755. X        {$$ = gen_pointer_attr(P_ATTR_3, $2, $3);}
  756. X    | '*' pointer
  757. X        {$$ = gen_pointer_attr(P_ATTR_4, NULL, $2);}
  758. X    ;
  759. X
  760. Xtype_qualifier_list:
  761. X      type_qualifier
  762. X        {$$ = gen_type_qualifier_list_attr($1);}
  763. X    | type_qualifier_list type_qualifier
  764. X        {$$ = add_type_qualifier($1, gen_type_qualifier_list_attr($2));}
  765. X    ;
  766. X
  767. Xparameter_type_list:
  768. X      parameter_list
  769. X    | parameter_list ',' TREEPOINT
  770. X        {$$ = Strcat($1, ", ...");}
  771. X    | error TREEPOINT
  772. X        {$$ = strmalloc("");}
  773. X    | error ',' TREEPOINT
  774. X        {$$ = strmalloc("");}
  775. X    | parameter_list ',' error
  776. X    ;
  777. X
  778. Xparameter_list:
  779. X      parameter_declaration
  780. X    | parameter_list ',' parameter_declaration
  781. X        {$$ = Strcatmany($1, 2, ",", $3);
  782. X         Free($3);
  783. X        }
  784. X    | error parameter_declaration
  785. X        {$$ = $2;}
  786. X    | error ',' parameter_declaration
  787. X        {$$ = $3;}
  788. X    ;
  789. X
  790. Xparameter_declaration:
  791. X      declaration_specifiers declarator
  792. X        {*convert_buffer = 0;
  793. X         convert_buffer = convert_ds_to_string(convert_buffer, $1);
  794. X         convert_buffer = convert_d_to_string(convert_buffer, $2);
  795. X         $$ = strmalloc(convert_buffer);
  796. X        }
  797. X    | declaration_specifiers abstract_declarator
  798. X        {$$ = Strcat(convert_ds_to_string(strmalloc(""), $1), $2);
  799. X         Free($2);
  800. X        }
  801. X    | declaration_specifiers
  802. X        {$$ = convert_ds_to_string(strmalloc(""), $1);}
  803. X    | declaration_specifiers error abstract_declarator
  804. X        {$$ = NULL;}
  805. X    | declaration_specifiers error 
  806. X        {$$ = NULL;}
  807. X    ;
  808. X
  809. Xopt_identifier_list:
  810. X      /* empty */
  811. X        {$$ = strmalloc("");}
  812. X    | identifier_list
  813. X        {DECERRFLAG;}
  814. X    ;
  815. X
  816. Xidentifier_list:
  817. X      IDENT
  818. X        {$$ = strmalloc($1->name);}
  819. X    | IDENT ',' identifier_list
  820. X        {$$ = Strcatmany(strmalloc($1->name), 2, ", ", $3);
  821. X         Free($3);
  822. X        }
  823. X    | error
  824. X        {$$ = strmalloc("");}
  825. X    | error identifier_list
  826. X        {$$ = $2;}
  827. X    | IDENT error identifier_list
  828. X        {$$ = $3;}
  829. X    | error ',' identifier_list
  830. X        {$$ = $3;}
  831. X    ;
  832. X
  833. Xinitializer:
  834. X      assignment_expression
  835. X    | '{' initializer_list '}'
  836. X        {$$ = Strcatmany(strmalloc("{ "), 2, $2, " }");
  837. X         Free($2);
  838. X        }
  839. X    | '{' initializer_list ',' '}'
  840. X        {$$ = Strcatmany(strmalloc("{ "), 2, $2, ", }");
  841. X         Free($2);
  842. X        }
  843. X    ;
  844. X
  845. Xinitializer_list:
  846. X      initializer
  847. X    | initializer_list ',' initializer
  848. X        {$$ = Strcatmany($1, 2, ",", $3);
  849. X         Free($3);
  850. X        }
  851. X    | error
  852. X        {$$ = strmalloc("");}
  853. X    | initializer_list error initializer
  854. X        {$$ = $1;
  855. X         Free($3);
  856. X        }
  857. X    | initializer_list ',' error
  858. X    | initializer_list error
  859. X    ;
  860. X
  861. Xtype_name:
  862. X      specifier_qualifier_list abstract_declarator
  863. X        {$$ = Strcat(convert_sql_to_string(strmalloc(""), $1), $2);
  864. X         Free($2);
  865. X        }
  866. X    | specifier_qualifier_list
  867. X        {$$ = convert_sql_to_string(strmalloc(""), $1);}
  868. X    | error
  869. X        {$$ = strmalloc("");}
  870. X    | specifier_qualifier_list error 
  871. X        {$$ = convert_sql_to_string(strmalloc(""), $1);}
  872. X    | specifier_qualifier_list error abstract_declarator
  873. X        {$$ = Strcat(convert_sql_to_string(strmalloc(""), $1), $3);
  874. X         Free($3);
  875. X        }
  876. X    ;
  877. X
  878. Xabstract_declarator:
  879. X      pointer
  880. X        {$$ = convert_p_to_string(strmalloc(""), $1);}
  881. X    | pointer direct_abstract_declarator
  882. X        {$$ = Strcat(convert_p_to_string(strmalloc(""), $1), $2);
  883. X         Free($2);
  884. X        }
  885. X    | direct_abstract_declarator
  886. X    | pointer error direct_abstract_declarator
  887. X        {$$ = NULL;}
  888. X    ;
  889. X
  890. Xdirect_abstract_declarator:
  891. X      '(' abstract_declarator ')'
  892. X        {$$ = Strcatmany(strmalloc("("), 2, $2, ")");
  893. X         Free($2);
  894. X        }
  895. X    | direct_abstract_declarator '[' constant_expression ']'
  896. X        {$$ = Strcatmany($1, 3, "[", $3, "]");
  897. X         Free($3);
  898. X        }
  899. X    | '[' constant_expression ']'
  900. X        {$$ = Strcatmany(strmalloc("["), 2, $2, "]");
  901. X         Free($2);
  902. X        } 
  903. X    | direct_abstract_declarator '[' ']'
  904. X        {$$ = Strcat($1, "[]");}
  905. X    | '[' ']'
  906. X        {$$ = strmalloc("[]");}
  907. X    | direct_abstract_declarator '(' parameter_type_list ')'
  908. X        {$$ = Strcatmany($1, 3, "(", $3, ")");
  909. X         Free($3);
  910. X        }
  911. X    | '(' parameter_type_list ')'
  912. X        {$$ = Strcatmany(strmalloc("("), 2, $2, ")");
  913. X         Free($2);
  914. X        }
  915. X    | direct_abstract_declarator '(' ')'
  916. X        {$$ = Strcat($1, "()");}
  917. X    | '(' ')'
  918. X        {$$ = strmalloc("()");}
  919. X    ;
  920. X
  921. Xstatement:
  922. X      labeled_statement
  923. X    | expression_statement
  924. X    |     {blk_push();}
  925. X      compound_statement
  926. X        {blk_pop();
  927. X         $$ = Strcatmany(strmalloc("{\n"),4,$2->decls,"\n",$2->stats,"\n}\n");
  928. X         Free($2->decls);
  929. X         /* Free($2->stats); */
  930. X         Free((char *) $2);
  931. X        }
  932. X    | selection_statement
  933. X    | iteration_statement
  934. X    | jump_statement
  935. X    | accept_statement
  936. X        {$$ = generate_transaction_code($1);
  937. X         DECERRFLAG;
  938. X        }
  939. X    | select_statement
  940. X    | destroy_statement
  941. X    ;
  942. X
  943. Xlabeled_statement:
  944. X      IDENT ':' statement
  945. X        {$$ = Strcatmany(strmalloc($1->name), 2, ":\n", $3);
  946. X         Free($3);
  947. X        }
  948. X    | IDENT error statement
  949. X        {$$ = $3;}
  950. X    | IDENT error ':' statement
  951. X        {$$ = $4;}
  952. X    | IDENT ':' error statement
  953. X        {$$ = $4;}
  954. X    | CASE constant_expression ':' statement
  955. X        {$$ = Strcatmany(strmalloc("case "), 3, $2, ":\n", $4);
  956. X         Free($2);
  957. X         Free($4);
  958. X        }
  959. X    | CASE error constant_expression ':' statement
  960. X        {$$ = $3;
  961. X         Free($5);
  962. X        }
  963. X    | CASE constant_expression error ':' statement
  964. X        {$$ = $2;
  965. X         Free($5);
  966. X        }
  967. X    | CASE constant_expression ':' error statement
  968. X        {$$ = $2;
  969. X         Free($5);
  970. X        }
  971. X    | DEFAULT ':' statement
  972. X        {$$ = Strcat(strmalloc("default:\n"), $3);
  973. X         Free($3);
  974. X        }
  975. X    | DEFAULT error statement
  976. X        {$$ = ($3);}
  977. X    | DEFAULT error ':' statement
  978. X        {$$ = ($4);}
  979. X    | DEFAULT ':' error statement
  980. X        {$$ = ($4);}
  981. X    ;
  982. X
  983. Xexpression_statement:
  984. X      expression ';'
  985. X        {$$ = Strcat($1, ";\n");
  986. X         yyerrok;
  987. X         DECERRFLAG;
  988. X        }
  989. X    | ';'
  990. X        {$$ = strmalloc(";\n");
  991. X         yyerrok;
  992. X         DECERRFLAG;
  993. X        }
  994. X    ;
  995. X
  996. Xcompound_statement:
  997. X      '{' declaration_list statement_list '}'
  998. X        {$$ = create_compound_attribute($2, $3);}
  999. X    | '{' statement_list '}'
  1000. X        {$$ = create_compound_attribute("", $2);}
  1001. X    | '{' declaration_list '}'
  1002. X        {$$ = create_compound_attribute($2, "");}
  1003. X    | '{' '}'
  1004. X        {$$ = create_compound_attribute("", "");}
  1005. X    | '{' error
  1006. X        {$$ = NULL;}
  1007. X    ;
  1008. X
  1009. Xstatement_list:
  1010. X      statement
  1011. X    | statement_list statement
  1012. X        {$$ = Strcat($1, $2);
  1013. X         Free($2);
  1014. X        }
  1015. X    | statement_list error
  1016. X    ;
  1017. X
  1018. Xselection_statement:
  1019. X      IF '(' expression ')' statement
  1020. X        {$$ = Strcatmany(strmalloc("if ("), 3, $3, ") ", $5);
  1021. X         Free($3);
  1022. X         Free($5);
  1023. X        }
  1024. X    | IF '(' expression ')' statement ELSE statement 
  1025. X        {$$ = Strcatmany(strmalloc("if ("),5,$3,") ",$5," else ",$7);
  1026. X         Free($3);
  1027. X         Free($5);
  1028. X         Free($7);
  1029. X        }
  1030. X    | IF error 
  1031. X        {$$ = strmalloc("");}
  1032. X    | IF '(' error
  1033. X        {$$ = strmalloc("");}
  1034. X    | IF '(' expression error
  1035. X        {$$ = $3;}
  1036. X    | IF '(' expression ')' error
  1037. X        {$$ = $3;}
  1038. X    | IF '(' expression ')' statement ELSE error 
  1039. X        {$$ = $3;}
  1040. X    | SWITCH '(' expression ')' statement
  1041. X        {$$ = Strcatmany(strmalloc("switch("), 3, $3, ") ", $5);
  1042. X         Free($3);
  1043. X         Free($5);
  1044. X        }
  1045. X    | SWITCH error
  1046. X        {$$ = strmalloc("");}
  1047. X    | SWITCH '(' error
  1048. X        {$$ = strmalloc("");}
  1049. X    | SWITCH '(' expression error
  1050. X        {$$ = $3;}
  1051. X    | SWITCH '(' expression ')' error
  1052. X        {$$ = $3;}
  1053. X    ;
  1054. X
  1055. Xiteration_statement:
  1056. X      WHILE '(' expression ')' statement
  1057. X        {$$ = Strcatmany(strmalloc("while("), 3, $3, ") ", $5);
  1058. X         Free($3);
  1059. X         Free($5);
  1060. X        }
  1061. X    | WHILE error
  1062. X        {$$ = strmalloc("");}
  1063. X    | WHILE '(' error
  1064. X        {$$ = strmalloc("");}
  1065. X    | WHILE '(' expression error
  1066. X        {$$ = $3;}
  1067. X    | WHILE '(' expression ')' error
  1068. X        {$$ = $3;}
  1069. X    | DO statement WHILE '(' expression ')' ';'
  1070. X        {$$ = Strcatmany(strmalloc("do "), 4, $2, " while(", $5,");\n");
  1071. X         Free($2);
  1072. X         Free($5);
  1073. X         yyerrok;
  1074. X         DECERRFLAG;
  1075. X        }
  1076. X    | DO error ';'
  1077. X        {$$ = strmalloc("");}
  1078. X    | DO statement error ';'
  1079. X        {$$ = $2;}
  1080. X    | DO statement WHILE error ';'
  1081. X        {$$ = $2;}
  1082. X    | DO statement WHILE '(' error ';'
  1083. X        {$$ = $2;}
  1084. X    | DO statement WHILE '(' expression error ';'
  1085. X        {$$ = $2;
  1086. X         Free($5);
  1087. X        }
  1088. X    | DO statement WHILE '(' expression ')' error ';'
  1089. X        {$$ = $2;
  1090. X         Free($5);
  1091. X        }
  1092. X    | FOR '(' expression ';' expression ';' expression ')' statement
  1093. X        {$$ = Strcatmany(strmalloc("for("), 7, $3, "; ", $5, "; ", $7, ") ", $9);
  1094. X         Free($3);
  1095. X         Free($5);
  1096. X         Free($7);
  1097. X         Free($9);
  1098. X        }
  1099. X    | FOR '(' ';' expression ';' expression ')' statement
  1100. X        {$$ = Strcatmany(strmalloc("for( ; "), 5, $4, "; ", $6, ") ", $8);
  1101. X         Free($4);
  1102. X         Free($6);
  1103. X         Free($8);
  1104. X        }
  1105. X    | FOR '(' expression ';' ';' expression ')' statement
  1106. X        {$$ = Strcatmany(strmalloc("for("), 5, $3, "; ; ", $6, ") ", $8);
  1107. X         Free($3);
  1108. X         Free($6);
  1109. X         Free($8);
  1110. X        }
  1111. X    | FOR '(' ';' ';' expression ')' statement
  1112. X        {$$ = Strcatmany(strmalloc("for( ; ; "), 3, $5, ") ", $7);
  1113. X         Free($5);
  1114. X         Free($7);
  1115. X        }
  1116. X    | FOR '(' expression ';' expression ';' ')' statement
  1117. X        {$$ = Strcatmany(strmalloc("for("), 5, $3, "; ", $5, "; ) ", $8);
  1118. X         Free($3);
  1119. X         Free($5);
  1120. X         Free($8);
  1121. X        }
  1122. X    | FOR '(' ';' expression ';' ')' statement
  1123. X        {$$ = Strcatmany(strmalloc("for( ; "), 3, $4, "; ) ", $7);
  1124. X         Free($4);
  1125. X         Free($7);
  1126. X        }
  1127. X    | FOR '(' expression ';' ';' ')' statement
  1128. X        {$$ = Strcatmany(strmalloc("for("), 3, $3, "; ; ) ", $7);
  1129. X         Free($3);
  1130. X         Free($7);
  1131. X        }
  1132. X    | FOR '(' ';' ';' ')' statement
  1133. X        {$$ = Strcat(strmalloc("for( ; ; ) "), $6);
  1134. X         Free($6);
  1135. X        }
  1136. X    | FOR error
  1137. X        {$$ = strmalloc("");}
  1138. X    | FOR '(' error
  1139. X        {$$ = strmalloc("");}
  1140. X    | FOR '(' error ')' statement
  1141. X        {$$ = $5;}
  1142. X    | FOR error ')' statement
  1143. X        {$$ = $4;}
  1144. X    ;
  1145. X
  1146. Xjump_statement:
  1147. X      GOTO IDENT ';'
  1148. X        {$$ = Strcatmany(strmalloc("goto "), 2, $2->name, ";\n");
  1149. X         DECERRFLAG;
  1150. X        }
  1151. X    | GOTO IDENT error ';'
  1152. X        {$$ = strmalloc("");}
  1153. X    | GOTO error ';'
  1154. X        {$$ = strmalloc("");
  1155. X         DECERRFLAG;
  1156. X        }
  1157. X    | CONTINUE ';'
  1158. X        {$$ = strmalloc("continue;\n");
  1159. X         DECERRFLAG;
  1160. X        }
  1161. X    | CONTINUE error ';'
  1162. X        {$$ = strmalloc("");
  1163. X         DECERRFLAG;
  1164. X        }
  1165. X    | BREAK ';'
  1166. X        {$$ = strmalloc("break;\n");
  1167. X         DECERRFLAG;
  1168. X        }
  1169. X    | BREAK error ';'
  1170. X        {$$ = strmalloc("");
  1171. X         DECERRFLAG;
  1172. X        }
  1173. X    | RETURN expression ';'
  1174. X        {$$ = Strcatmany(strmalloc("return "), 2, $2, ";\n");
  1175. X         Free($2);
  1176. X         DECERRFLAG;
  1177. X        }
  1178. X    | RETURN error ';'
  1179. X        {$$ = strmalloc("");}
  1180. X    | RETURN ';'
  1181. X        {$$ = strmalloc("return;\n");
  1182. X         DECERRFLAG;
  1183. X        }
  1184. X    | TRETURN expression ';'
  1185. X        {$$ = generate_treturn_code($2);
  1186. X         Free($2);
  1187. X         DECERRFLAG;
  1188. X        }
  1189. X    | TRETURN ';'
  1190. X        {$$ = generate_treturn_code(NULL);
  1191. X         DECERRFLAG;
  1192. X        }
  1193. X    ;
  1194. X
  1195. Xaccept_statement:
  1196. X      ACCEPT IDENT '(' opt_identifier_list ')'
  1197. X        {$2 = add_transaction_label(check_transaction($2));
  1198. X         blk_push();
  1199. X         (void) reenter_transaction_params($2);
  1200. X        }
  1201. X      compound_statement
  1202. X        {blk_pop();
  1203. X         $$ = create_accept_attribute($2, $7);
  1204. X        }
  1205. X      | ACCEPT IDENT ';'
  1206. X        {$$ = create_accept_attribute(check_transaction($2), create_compound_attribute("", ""));}
  1207. X    | ACCEPT error 
  1208. X        {yynerrs--;
  1209. X         Errno = EINACCSTAT;
  1210. X         Error(NULL, "");
  1211. X        }
  1212. X      ';'
  1213. X        {yyerrok;
  1214. X         $$ = create_accept_attribute(NULL, NULL);
  1215. X        }
  1216. X    | ACCEPT error 
  1217. X        {yynerrs--;
  1218. X         Errno = EINACCSTAT2;
  1219. X         Error(NULL, "");
  1220. X        }
  1221. X      IDENT '(' opt_identifier_list ')' ';'
  1222. X        {yyerrok;
  1223. X         $$ = create_accept_attribute(NULL, NULL);
  1224. X        }
  1225. X    | ACCEPT IDENT error 
  1226. X        {yynerrs--;
  1227. X         Errno = EINACCSTAT3;
  1228. X         Error(NULL, "");
  1229. X        }
  1230. X      '(' opt_identifier_list ')' ';'
  1231. X        {yyerrok;
  1232. X         $$ = create_accept_attribute(NULL, NULL);
  1233. X        }
  1234. X    | ACCEPT IDENT '(' opt_identifier_list ')' error 
  1235. X        {yynerrs--;
  1236. X         Errno = EINACCSTAT4;
  1237. X         Error(NULL, "");
  1238. X        }
  1239. X      ';'
  1240. X        {yyerrok;
  1241. X         $$ = create_accept_attribute(NULL, NULL);
  1242. X        }
  1243. X    ;
  1244. X
  1245. Xselect_statement:
  1246. X      SELECT '{' select_list '}'
  1247. X        {$$ = generate_select_code($3);}
  1248. X    | SELECT error 
  1249. X        {yynerrs--;
  1250. X         Errno = EINSELSTAT;
  1251. X         Error(NULL, "");
  1252. X         $$ = strmalloc("");
  1253. X        }
  1254. X    ;
  1255. X
  1256. Xselect_list:
  1257. X      select_part
  1258. X    | select_part OR select_list
  1259. X        {$$ = link_select_attributes($1, $3);}
  1260. X    | error
  1261. X        {yynerrs--;
  1262. X         Errno = EINSELSTAT;
  1263. X         Error(NULL, "");
  1264. X         $$ = create_select_attribute(ERROR, NULL, NULL);
  1265. X        }
  1266. X    | error 
  1267. X        {yynerrs--;
  1268. X         Errno = EINSELSTAT;
  1269. X         Error(NULL, "");
  1270. X        }
  1271. X      select_list
  1272. X        {$$ = $3;}
  1273. X    | error 
  1274. X        {yynerrs--;
  1275. X         Errno = EINSELSTAT2;
  1276. X         Error(NULL, "");
  1277. X        }
  1278. X      OR select_list
  1279. X        {$$ = $4;}
  1280. X    ;
  1281. X
  1282. Xselect_part:
  1283. X      alternative
  1284. X    | '(' expression ')' ':' alternative
  1285. X        {$$ = add_guard_to_attr($5, $2);}
  1286. X    | error 
  1287. X        {yynerrs--;
  1288. X         Errno = EINSELPART;
  1289. X         Error(NULL, "");
  1290. X        }
  1291. X      ':' alternative
  1292. X        {$$ = $4;}
  1293. X    ;
  1294. X
  1295. Xalternative:
  1296. X      accept_alternative
  1297. X    | terminate_alternative
  1298. X    | immediate_alternative 
  1299. X        {$$ = create_select_attribute(ALT_IMMEDIATE, NULL, $1);}
  1300. X    ;
  1301. X
  1302. Xaccept_alternative:
  1303. X      accept_statement statement_list
  1304. X        {$$ = create_select_attribute(ALT_ACCEPT, $1, $2);}
  1305. X    | accept_statement error
  1306. X        {yynerrs--;
  1307. X         Errno = EINACCALTERN;
  1308. X         Error(NULL, "");
  1309. X         $$ = create_select_attribute(ERROR, NULL, NULL);
  1310. X        }
  1311. X    | accept_statement error 
  1312. X        {yynerrs--;
  1313. X         Errno = EINACCALTERN;
  1314. X         Error(NULL, "");
  1315. X        }
  1316. X      statement_list
  1317. X        {$$ = create_select_attribute(ERROR, NULL, NULL);}
  1318. X    ;
  1319. X
  1320. Xterminate_alternative:
  1321. X      TERMINATE
  1322. X        {$$ = create_select_attribute(ALT_TERMINATE, NULL, NULL);}
  1323. X    ;
  1324. X
  1325. Ximmediate_alternative:
  1326. X      labeled_statement
  1327. X    | expression_statement
  1328. X    | compound_statement
  1329. X        {$$ = Strcatmany(strmalloc("{\n"),4,$1->decls,"\n",$1->stats,"\n}\n");
  1330. X         Free($1->decls);
  1331. X         Free($1->stats);
  1332. X         Free((char *) $1);
  1333. X        }
  1334. X    | selection_statement
  1335. X    | iteration_statement
  1336. X    | jump_statement
  1337. X    ;
  1338. X
  1339. Xdestroy_statement:
  1340. X      DESTROY '(' postfix_expression ')'
  1341. X        {$$ = generate_destroy_process_code($3->codestr);}
  1342. X    | DESTROY error
  1343. X        {yynerrs--;
  1344. X         Errno = EINDESTRSTAT;
  1345. X         Error(NULL, "");
  1346. X         $$ = strmalloc("");
  1347. X        }
  1348. X    ;
  1349. X
  1350. Xexpression:
  1351. X      assignment_expression
  1352. X    | expression ',' assignment_expression
  1353. X        {$$ = Strcatmany($1, 2, ", ", $3);
  1354. X         Free($3);
  1355. X        }
  1356. X    | expression ',' error
  1357. X    | error ',' assignment_expression
  1358. X        {$$ = $3;}
  1359. X    ;
  1360. X
  1361. Xassignment_expression:
  1362. X      conditional_expression
  1363. X    | unary_expression assignment_operator assignment_expression
  1364. X        {$$ = Strcatmany($1, 2, $2, $3);
  1365. X         Free($3);
  1366. X        }
  1367. X    | unary_expression assignment_operator error
  1368. X        {Free($2);}
  1369. X    | unary_expression assignment_operator error assignment_expression
  1370. X        {Free($2);
  1371. X         Free($4);
  1372. X        }
  1373. X    ;
  1374. X
  1375. Xassignment_operator:
  1376. X      '='
  1377. X        {$$ = " = ";}
  1378. X    | MUL_ASSIGN
  1379. X        {$$ = " *= ";}
  1380. X    | DIV_ASSIGN
  1381. X        {$$ = " /= ";}
  1382. X    | MOD_ASSIGN
  1383. X        {$$ = " %= ";}
  1384. X    | PLUS_ASSIGN
  1385. X        {$$ = " += ";}
  1386. X    | MINUS_ASSIGN
  1387. X        {$$ = " -= ";}
  1388. X    | LSHIFT_ASSIGN
  1389. X        {$$ = " <<= ";}
  1390. X    | RSHIFT_ASSIGN
  1391. X        {$$ = " >>= ";}
  1392. X    | AMPERS_ASSIGN
  1393. X        {$$ = " &= ";}
  1394. X    | HAT_ASSIGN
  1395. X        {$$ = " ^= ";}
  1396. X    | PIPE_ASSIGN
  1397. X        {$$ = " |= ";}
  1398. X    ;
  1399. X
  1400. Xconditional_expression:
  1401. X      logical_OR_expression
  1402. X    | logical_OR_expression '?' expression ':' conditional_expression
  1403. X        {$$ = Strcatmany($1, 4, " ? ", $3, " : ", $5);
  1404. X         Free($3);
  1405. X         Free($5);
  1406. X        }
  1407. X    | timed_transaction_call
  1408. X    ;
  1409. X
  1410. Xtimed_transaction_call:
  1411. X      WITHIN logical_OR_expression '?' '(' transaction_call
  1412. X      ':' expression ')'
  1413. X        {$$ = generate_call_transaction_code($2, $5->target, $5->symbol, $5->arg, $7);}
  1414. X    | WITHIN error
  1415. X        {yynerrs--;
  1416. X         Errno = EINTIMEDTRANS;
  1417. X         Error(NULL, "");
  1418. X         $$ = strmalloc("");
  1419. X        }
  1420. X    | WITHIN logical_OR_expression error 
  1421. X        {yynerrs--;
  1422. X         Errno = EINTIMEDTRANS;
  1423. X         Error(NULL, "");
  1424. X        }
  1425. X      ')'
  1426. X        {$$ = strmalloc("");}
  1427. X    ;
  1428. X
  1429. Xconstant_expression:
  1430. X      conditional_expression
  1431. X    ;
  1432. X
  1433. Xlogical_OR_expression:
  1434. X      logical_AND_expression
  1435. X    | logical_OR_expression LOGOR logical_AND_expression
  1436. X        {$$ = Strcatmany($1, 2, " || ", $3);
  1437. X         Free($3);
  1438. X        }
  1439. X    ;
  1440. X
  1441. Xlogical_AND_expression:
  1442. X      inclusive_OR_expression
  1443. X    | logical_AND_expression LOGAND inclusive_OR_expression
  1444. X        {$$ = Strcatmany($1, 2, " && ", $3);
  1445. X         Free($3);
  1446. X        }
  1447. X    ;
  1448. X
  1449. Xinclusive_OR_expression:
  1450. X      exclusive_OR_expression
  1451. X    | inclusive_OR_expression '|' exclusive_OR_expression
  1452. X        {$$ = Strcatmany($1, 2, " | ", $3);
  1453. X         Free($3);
  1454. X        }
  1455. X    ;
  1456. X
  1457. Xexclusive_OR_expression:
  1458. X      AND_expression
  1459. X    | exclusive_OR_expression '^' AND_expression
  1460. X        {$$ = Strcatmany($1, 2, " ^ ", $3);
  1461. X         Free($3);
  1462. X        }
  1463. X    ;
  1464. X
  1465. XAND_expression:
  1466. X      equality_expression
  1467. X    | AND_expression '&' equality_expression
  1468. X        {$$ = Strcatmany($1, 2, " & ", $3);
  1469. X         Free($3);
  1470. X        }
  1471. X    ;
  1472. X
  1473. Xequality_expression:
  1474. X      relational_expression
  1475. X    | equality_expression EEQUAL relational_expression
  1476. X        {$$ = Strcatmany($1, 2, " == ", $3);
  1477. X         Free($3);
  1478. X        }
  1479. X    | equality_expression NOTEQUAL relational_expression
  1480. X        {$$ = Strcatmany($1, 2, " != ", $3);
  1481. X         Free($3);
  1482. X        }
  1483. X    ;
  1484. X
  1485. Xrelational_expression:
  1486. X      shift_expression
  1487. X    | relational_expression '<' shift_expression
  1488. X        {$$ = Strcatmany($1, 2, " < ", $3);
  1489. X         Free($3);
  1490. X        }
  1491. X    | relational_expression '>' shift_expression
  1492. X        {$$ = Strcatmany($1, 2, " > ", $3);
  1493. X         Free($3);
  1494. X        }
  1495. X    | relational_expression LE shift_expression
  1496. X        {$$ = Strcatmany($1, 2, " <= ", $3);
  1497. X         Free($3);
  1498. X        }
  1499. X    | relational_expression GE shift_expression
  1500. X        {$$ = Strcatmany($1, 2, " >= ", $3);
  1501. X         Free($3);
  1502. X        }
  1503. X    ;
  1504. X
  1505. Xshift_expression:
  1506. X      additive_expression
  1507. X    | shift_expression LSHIFT additive_expression
  1508. X        {$$ = Strcatmany($1, 2, " << ", $3);
  1509. X         Free($3);
  1510. X        }
  1511. X    | shift_expression RSHIFT additive_expression
  1512. X        {$$ = Strcatmany($1, 2, " >> ", $3);
  1513. X         Free($3);
  1514. X        }
  1515. X    ;
  1516. X
  1517. Xadditive_expression:
  1518. X      multiplicative_expression
  1519. X    | additive_expression '+' multiplicative_expression
  1520. X        {$$ = Strcatmany($1, 2, " + ", $3);
  1521. X         Free($3);
  1522. X        }
  1523. X    | additive_expression '-' multiplicative_expression
  1524. X        {$$ = Strcatmany($1, 2, " - ", $3);
  1525. X         Free($3);
  1526. X        }
  1527. X    ;
  1528. X
  1529. Xmultiplicative_expression:
  1530. X      cast_expression
  1531. X    | multiplicative_expression '*' cast_expression
  1532. X        {$$ = Strcatmany($1, 2, " * ", $3);
  1533. X         Free($3);
  1534. X        }
  1535. X    | multiplicative_expression '/' cast_expression
  1536. X        {$$ = Strcatmany($1, 2, " / ", $3);
  1537. X         Free($3);
  1538. X        }
  1539. X    | multiplicative_expression '%' cast_expression
  1540. X        {$$ = Strcatmany($1, 2, " % ", $3);
  1541. X         Free($3);
  1542. X        }
  1543. X    ;
  1544. X
  1545. Xcast_expression:
  1546. X      unary_expression
  1547. X    | '(' type_name ')' cast_expression
  1548. X        {$$ = Strcatmany(strmalloc("("), 3, $2, ") ", $4);
  1549. X         Free($2);
  1550. X         Free($4);
  1551. X        }
  1552. X    ;
  1553. X
  1554. Xunary_expression:
  1555. X      postfix_expression
  1556. X        {$$=$1->codestr;}
  1557. X    | PLUSPLUS unary_expression
  1558. X        {$$ = Strcat(strmalloc("++"), $2);
  1559. X         Free($2);
  1560. X        }
  1561. X    | PLUSPLUS error
  1562. X        {$$ = strmalloc("");}
  1563. X    | MINUSMINUS unary_expression
  1564. X        {$$ = Strcat(strmalloc("--"), $2);
  1565. X         Free($2);
  1566. X        }
  1567. X    | MINUSMINUS error
  1568. X        {$$ = strmalloc("");}
  1569. X    | unary_operator cast_expression
  1570. X        {$$ = Strcat($1, $2);
  1571. X         Free($2);
  1572. X        }
  1573. X    | unary_operator error
  1574. X    | SIZEOF unary_expression
  1575. X        {$$ = Strcat(strmalloc("sizeof "), $2);
  1576. X         Free($2);
  1577. X        }
  1578. X    | SIZEOF error
  1579. X        {$$ = strmalloc("");}
  1580. X    | SIZEOF '(' type_name ')'
  1581. X        {$$ = Strcatmany(strmalloc("sizeof("), 2, $3, ")");
  1582. X         Free($3);
  1583. X        }
  1584. X    ;
  1585. X
  1586. Xunary_operator:
  1587. X      '&'
  1588. X        {$$ = strmalloc("&");}
  1589. X    | '*'
  1590. X        {$$ = strmalloc("*");}
  1591. X    | '+'
  1592. X        {$$ = strmalloc("+");}
  1593. X    | '-'
  1594. X        {$$ = strmalloc("-");}
  1595. X    | '~'
  1596. X        {$$ = strmalloc("~");}
  1597. X    | '!'
  1598. X        {$$ = strmalloc("!");}
  1599. X    ;
  1600. X
  1601. Xpostfix_expression:
  1602. X      primary_expression
  1603. X        {$$ = create_post_expr_attr($1);}
  1604. X    | postfix_expression '[' expression ']'
  1605. X        {$1->codestr = Strcatmany($1->codestr, 3, "[", $3, "]");
  1606. X         Free($3);
  1607. X        }
  1608. X     | postfix_expression '(' argument_expression_list ')'
  1609. X        {$1->codestr = Strcatmany($1->codestr, 3, "(", $3, ")");
  1610. X         Free($3);
  1611. X        }
  1612. X    | postfix_expression '(' ')'
  1613. X        {$1->codestr = Strcat($1->codestr, "()");}
  1614. X    | postfix_expression '.' IDENT
  1615. X        {$1->idents = update_post_expr_attr($1->idents, $3);
  1616. X         $1->codestr = Strcatmany($1->codestr, 2, ".", $3->name);
  1617. X        }
  1618. X    | postfix_expression '.' error
  1619. X    | postfix_expression ARROW IDENT
  1620. X        {$1->idents = update_post_expr_attr($1->idents, $3);
  1621. X         $1->codestr = Strcatmany($1->codestr, 2, "->", $3->name);
  1622. X        }
  1623. X    | postfix_expression ARROW error
  1624. X    | postfix_expression PLUSPLUS
  1625. X        {$$->codestr = Strcat($1->codestr, "++");}
  1626. X    | postfix_expression MINUSMINUS
  1627. X        {$$->codestr = Strcat($1->codestr, "--");}
  1628. X     | process_creation 
  1629. X        {$$=create_post_expr_attr($1);}
  1630. X    | transaction_call
  1631. X        {$1->target=generate_call_transaction_code(NULL,$1->target, $1->symbol, $1->arg, NULL);
  1632. X         $$=create_post_expr_attr($1->target);
  1633. X        }
  1634. X    ;
  1635. X
  1636. Xprocess_creation:
  1637. X      CREATE IDENT '(' process_arguments ')' process_location
  1638. X        {$$ = generate_process_creation_code($2, $4, $6);}
  1639. X    | CREATE error
  1640. X        {yynerrs--;
  1641. X         Errno = EINPROCCREATE;
  1642. X         Error(NULL, "");
  1643. X         $$ = strmalloc("");
  1644. X        }
  1645. X    | CREATE error 
  1646. X        {yynerrs--;
  1647. X         Errno = EINPROCCREATE2;
  1648. X         Error(NULL, "");
  1649. X        }
  1650. X      IDENT '(' process_arguments ')' process_location
  1651. X        {$$ = $8;}
  1652. X    | CREATE IDENT error 
  1653. X        {yynerrs--;
  1654. X         Errno = EINPROCCREATE3;
  1655. X         Error(NULL, "");
  1656. X        }
  1657. X      '(' process_arguments ')' process_location
  1658. X        {$$ = $8;}
  1659. X    ;
  1660. X
  1661. Xprocess_arguments:
  1662. X      /* empty */
  1663. X        {$$ = (ARG_LIST *) NULL;}
  1664. X    | process_arg_expr_list
  1665. X    ;
  1666. X
  1667. Xprocess_arg_expr_list:
  1668. X      assignment_expression
  1669. X        {$$ = create_arg_list_elem($1);}
  1670. X    | assignment_expression ',' process_arg_expr_list 
  1671. X        {$$ = link_arguments(create_arg_list_elem($1), $3);}
  1672. X    | error
  1673. X        {yynerrs--;
  1674. X         Errno = EINPROCARGS;
  1675. X         Error(NULL, "");
  1676. X         $$ = (ARG_LIST *) NULL;
  1677. X        }
  1678. X    | error 
  1679. X        {yynerrs--;
  1680. X         Errno = EINPROCARGS;
  1681. X         Error(NULL, "");
  1682. X        }
  1683. X      ',' process_arg_expr_list 
  1684. X        {$$ = $4;}
  1685. X    | assignment_expression error 
  1686. X        {Free($1);
  1687. X         yynerrs--;
  1688. X         Errno = EINPROCARGS;
  1689. X         Error(NULL, "");
  1690. X        }
  1691. X      process_arg_expr_list 
  1692. X        {$$ = $4;}
  1693. X    ;
  1694. X
  1695. Xprocess_location:
  1696. X      LOCAL
  1697. X        {$$ = strmalloc("\"local\"");}
  1698. X    | AT HOST '(' assignment_expression ')'
  1699. X        {$$ = $4;}
  1700. X    | /* empty */
  1701. X        {$$ = strmalloc("NULL");}
  1702. X    | AT error
  1703. X        {yynerrs--;
  1704. X         Errno = EINPROCLOC;
  1705. X         Error(NULL, "");
  1706. X         $$ = strmalloc("");
  1707. X        }
  1708. X    | AT HOST error
  1709. X        {yynerrs--;
  1710. X         Errno = EINPROCLOC;
  1711. X         Error(NULL, "");
  1712. X         $$ = strmalloc("");
  1713. X        }
  1714. X    ;
  1715. X
  1716. Xtransaction_call:
  1717. X       postfix_expression 
  1718. X        {blk_push;}
  1719. X      '@' IDENT 
  1720. X        {blk_pop;}
  1721. X      '(' process_arguments ')' 
  1722. X        {$$ = create_trans_attr($1, get_process($4), $7);}
  1723. X/*    | postfix_expression '@' error
  1724. X        {$$->target=$1->codestr;
  1725. X         $$->symbol=NULL;
  1726. X         $$->arg=NULL;        
  1727. X         yynerrs--;
  1728. X         Errno = EINTRANSCALL;
  1729. X         Error(NULL, "");
  1730. X        }
  1731. X    | postfix_expression '@' IDENT error 
  1732. X        {$$->target=$1->codestr;
  1733. X         $$->symbol=NULL;
  1734. X         $$->arg=NULL;        
  1735. X         yynerrs--;
  1736. X         Errno = EINTRANSCALL;
  1737. X         Error(NULL, "");
  1738. X        }
  1739. X*/    ;
  1740. X
  1741. Xprimary_expression:
  1742. X      IDENT
  1743. X        {$$ = strmalloc($1->name);}
  1744. X    | constant
  1745. X    | STR_CONST
  1746. X        {$$ = strmalloc(yytext);}
  1747. X    | '(' expression ')'
  1748. X        {$$ = Strcatmany(strmalloc("("), 2, $2, ")");
  1749. X         Free($2);
  1750. X        }
  1751. X    ;
  1752. X
  1753. Xargument_expression_list:
  1754. X      assignment_expression
  1755. X    | argument_expression_list ',' assignment_expression
  1756. X        {$$ = Strcatmany($1, 2, ",", $3);
  1757. X         Free($3);
  1758. X        }
  1759. X    | error
  1760. X        {$$ = strmalloc("");}
  1761. X    | argument_expression_list error 
  1762. X    | argument_expression_list error assignment_expression
  1763. X    ;
  1764. X
  1765. Xconstant:
  1766. X      INT_CONST
  1767. X        {$$ = strmalloc(yytext);}
  1768. X    | CHR_CONST
  1769. X        {$$ = strmalloc(yytext);}
  1770. X    | FLOAT_CONST
  1771. X        {$$ = strmalloc(yytext);}
  1772. X    | ENUMCONST /*IDENT */
  1773. X        {$$ = strmalloc(yytext);}
  1774. X    ;
  1775. X
  1776. X%%
  1777. X
  1778. X#include "lex.yy.c"
  1779. END_OF_FILE
  1780. if test 42425 -ne `wc -c <'dcc/dcc.y'`; then
  1781.     echo shar: \"'dcc/dcc.y'\" unpacked with wrong size!
  1782. fi
  1783. # end of 'dcc/dcc.y'
  1784. fi
  1785. if test -f 'lib/ipc_msgsem.c' -a "${1}" != "-c" ; then 
  1786.   echo shar: Will not clobber existing file \"'lib/ipc_msgsem.c'\"
  1787. else
  1788. echo shar: Extracting \"'lib/ipc_msgsem.c'\" \(41235 characters\)
  1789. sed "s/^X//" >'lib/ipc_msgsem.c' <<'END_OF_FILE'
  1790. X/***************************************************************************
  1791. X *                                                                         *
  1792. X * @@@@  @@@ @@@@@ @@@@@ @@@@@ @@@ @@@@  @   @ @@@@@ @@@@@ @@@@       @@@  *
  1793. X * @   @  @  @       @   @   @  @  @   @ @   @   @   @     @   @     @   @ *
  1794. X * @   @  @  @@@@@   @   @@@@@  @  @@@@@ @   @   @   @@@@@ @   @     @     *
  1795. X * @   @  @      @   @   @ @    @  @   @ @   @   @   @     @   @     @   @ *
  1796. X * @@@@  @@@ @@@@@   @   @  @  @@@ @@@@  @@@@@   @   @@@@@ @@@@       @@@  *
  1797. X *                                                                         *
  1798. X *              A compiler for distributed programming with C              *
  1799. X *                                                                         *
  1800. X *                         i p c _ m s g s e m . c                         *
  1801. X *                                                                         *
  1802. X *                            Package : Runtime Library                    *
  1803. X *                            Version : 1.0                                *
  1804. X *                       CreationDate : 10.07.90                           *
  1805. X *                         LastUpDate : 15.10.90                           *
  1806. X *                                                                         *
  1807. X * This file contains the hardware dependent routines building the message *
  1808. X * passing layer based on message queues and semaphores.                   *
  1809. X *                                                                         *
  1810. X *               Copyright (C) 1990-1994 by Christoph Pleier               *
  1811. X *                          All rights reserved!                           *
  1812. X ***************************************************************************/
  1813. X
  1814. X/*
  1815. X * This file is part of the Distributed C Development Environment (DCDE).
  1816. X * DCDE is free software; you can redistribute it and/or modify
  1817. X * it under the terms written in the README-file. 
  1818. X * DCDE is distributed in the hope that it will be useful,
  1819. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1820. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  1821. X * See the file README for more details.
  1822. X */
  1823. X
  1824. X#include <stdio.h>
  1825. X#include <sys/types.h>
  1826. X#include <sys/ipc.h>
  1827. X#include <sys/msg.h>
  1828. X#include <sys/sem.h>
  1829. X#include <errno.h>
  1830. X#include <memory.h>
  1831. X#include <signal.h>
  1832. X#include "ipc_msgsem.h"
  1833. X#include "run_Errno.h"
  1834. X
  1835. X/* define this to add code to display additional informations about: */
  1836. X#define DEBUG_IPC     /* message pssing */
  1837. X/* #define DEBUG_MSG     /* semaphore and message queue actions */
  1838. X
  1839. X/* To avoid that processes whose connection attempt is refused several times
  1840. X * (e.g. if the called process tries itself to connect to the calling process)
  1841. X * let grow the load of the computer nodes because of the busy waiting
  1842. X * character, we raise each time a connection attempt is refused the delay 
  1843. X * until the connecting process is allowed to retry the attempt.
  1844. X * The delay starts at MCON_RETRY_DELAY_MIN and is raised in steps of
  1845. X * MCON_RETRY_DELAY_STEP until MCON_RETRY_DELAY_MAX. After the connection
  1846. X * attempt succeeded or the operation is timed out the delay is reset to the 
  1847. X * min. value. 
  1848. X * 
  1849. X * Note: the values specify milliseconds
  1850. X */
  1851. X#define MCON_RETRY_DELAY_MIN   100
  1852. X#define MCON_RETRY_DELAY_MAX   5000
  1853. X#define MCON_RETRY_DELAY_STEP  100
  1854. X
  1855. X/* to store the actual retry delay */
  1856. Xint mcon_retry_delay = MCON_RETRY_DELAY_MIN;
  1857. X
  1858. X#ifdef DEBUG_IPC
  1859. X/* the flag to control the debug messages output */
  1860. Xint _debug_ipc = 0;
  1861. X#endif /* DEBUG_IPC /**/
  1862. X
  1863. X/* the used external global variables */
  1864. Xextern int   errno,        /* system error code */
  1865. X             Errno,        /* function error code */
  1866. X             _debugflush;    /* flush debug messages or not */
  1867. Xextern char *sys_errlist[],    /* system error messages */
  1868. X            *_programname,    /* name of program */
  1869. X            *_processname,    /* name of process */
  1870. X             _processprefix[];    /* process specifying string */
  1871. Xextern FILE *_debugout;        /* where to write the debug messages */
  1872. X
  1873. X/* the timeout flag */
  1874. Xstatic int timeout;
  1875. X
  1876. X/* set timer, if time equals 0 clear timer */
  1877. X#define SETTIMER(time)        timeout = FALSE; \
  1878. X                signal(SIGALRM, timeout_proc); \
  1879. X                (void) alarm(time);
  1880. X
  1881. X#ifdef DEBUG_IPC
  1882. X# define DEBUGPUTS(msg)        if (_debug_ipc) { \
  1883. X                    fprintf(_debugout, "[ipc] %s %s\n", \
  1884. X                        _processprefix, msg); \
  1885. X                    if (_debugflush) \
  1886. X                        fflush(_debugout); \
  1887. X                }
  1888. X# define DEBUGDISPERR(msg)    if (_debug_ipc) { \
  1889. X                    fprintf(_debugout, "[ipc] %s error: %s\n", \
  1890. X                        _processprefix, msg); \
  1891. X                    fprintf(_debugout, "[ipc] %s reason: %s\n",\
  1892. X                        _processprefix, sys_errlist[errno]); \
  1893. X                    if (_debugflush) \
  1894. X                        fflush(_debugout); \
  1895. X                }
  1896. X#else
  1897. X# define DEBUGPUTS(msg)        { /* nothing */ }
  1898. X# define DEBUGDISPERR(msg)    { /* nothing */ }
  1899. X#endif
  1900. X
  1901. X/* if timeout is set, return ERROR */
  1902. X#define RETURN_IF_TIMEOUT    if (timeout) { \
  1903. X                    DEBUGPUTS("TIMEOUT"); \
  1904. X                    Errno = ETIMEOUT; \
  1905. X                    return(ERROR); \
  1906. X                }
  1907. X
  1908. X/******************************************************************************
  1909. X * timeout_proc()                                                             *
  1910. X *                                                                            *
  1911. X * Sets the timeout flag 'timeout' to indicate a timeout error.               *
  1912. X *                                                                            *
  1913. X * Return values: none!                                                       *
  1914. X ******************************************************************************/
  1915. Xstatic int
  1916. Xtimeout_proc()
  1917. X{
  1918. X    DEBUGPUTS("***** timeout_proc():");
  1919. X    timeout = TRUE;
  1920. X} /* timeout_proc */
  1921. X
  1922. X/******************************************************************************
  1923. X * create_msq()                                                               *
  1924. X *                                                                            *
  1925. X * Creates a message queue identifier, an associated message queue and data   *
  1926. X * structure.                                                                 *
  1927. X *                                                                            *
  1928. X * Return values: new msqid upon success / -1 = error                         *
  1929. X ******************************************************************************/
  1930. Xstatic int
  1931. Xcreate_msq()
  1932. X{
  1933. X#ifdef DEBUG_MSG
  1934. X    puts("[msg] ***** create_msq()");
  1935. X#endif /* DEBUG_MSG /**/
  1936. X    return(msgget((key_t) IPC_PRIVATE, IPC_CREAT | MSG_PERMISSION));
  1937. X} /* create_msq */
  1938. X
  1939. X/******************************************************************************
  1940. X * remove_msq()                                                               *
  1941. X *                                                                            *
  1942. X * Removes the message queue identifier specified by 'msqid' from the system  *
  1943. X * destroys the message queue and data structure associated with it.          *
  1944. X *                                                                            *
  1945. X * Return values: 0 = success / -1 = error                                    *
  1946. X ******************************************************************************/
  1947. Xstatic int
  1948. Xremove_msq(msqid)
  1949. Xint msqid;
  1950. X{
  1951. X    static struct msqid_ds dummy;
  1952. X
  1953. X#ifdef DEBUG_MSG
  1954. X    puts("[msg] ***** remove_msq()");
  1955. X    printf("[msg] params: msqid = %d\n", msqid);
  1956. X#endif /* DEBUG_MSG /**/
  1957. X    return(msgctl(msqid, IPC_RMID, &dummy));
  1958. X} /* remove_msq */
  1959. X
  1960. X/******************************************************************************
  1961. X * msq_set_permission()                                                       *
  1962. X *                                                                            *
  1963. X * Sets the value of the following members of the data structure associated   *
  1964. X * with 'msqid' into the structure pointed to by 'buf':                       *
  1965. X * msg_perm.uid, msg_perm.gid, msg_perm.mode, msg_qbytes                      *
  1966. X *                                                                            *
  1967. X * Return values: 0 = success / -1 = error                                    *
  1968. X ******************************************************************************/
  1969. Xstatic int
  1970. Xmsq_set_permission(msqid, uid, gid, mode, qbytes)
  1971. Xint msqid;
  1972. Xushort uid, gid, mode, qbytes;
  1973. X{
  1974. X    static struct msqid_ds msqbuf;
  1975. X
  1976. X#ifdef DEBUG_MSG
  1977. X    puts("[msg] ***** msq_set_permission()");
  1978. X    printf("[msg] params: msqid = %d, uid = %d, gid = %d\n", 
  1979. X        msqid, uid, gid);
  1980. X    printf("[msg]            mode = %d, qbytes = %d\n", mode, qbytes);
  1981. X#endif /* DEBUG_MSG /**/
  1982. X    msqbuf.msg_perm.uid  = uid;
  1983. X    msqbuf.msg_perm.gid  = gid;
  1984. X    msqbuf.msg_perm.mode = mode;
  1985. X    msqbuf.msg_qbytes    = qbytes;
  1986. X    return(msgctl(msqid, IPC_SET, &msqbuf));
  1987. X} /* msq_set_permission */
  1988. X
  1989. X/******************************************************************************
  1990. X * msq_display_status()                                                       *
  1991. X *                                                                            *
  1992. X * Displays the current value of each member of the data structure associated *
  1993. X * with the message queue identifier 'msqid'.                                 *
  1994. X *                                                                            *
  1995. X * Return values: 0 = success / -1 = error                                    *
  1996. X ******************************************************************************/
  1997. Xstatic int
  1998. Xmsq_display_status(msqid)
  1999. Xint msqid;
  2000. X{
  2001. X    static struct msqid_ds msqbuf;
  2002. X
  2003. X#ifdef DEBUG_MSG
  2004. X    puts("[msg] ***** msq_display_status()");
  2005. X    printf("[msg] params: msqid = %d\n", msqid);
  2006. X#endif /* DEBUG_MSG /**/
  2007. X    printf("Values associated to message queue identifier '%d':\n", msqid); 
  2008. X    if (msq_get_status(msqid, &msqbuf) == -1)
  2009. X        return(-1);
  2010. X    printf("             creator user id : %d\n", msqbuf.msg_perm.cuid);
  2011. X    printf("            creator group id : %d\n", msqbuf.msg_perm.cgid);
  2012. X    printf("                     user id : %d\n", msqbuf.msg_perm.uid);
  2013. X    printf("                    group id : %d\n", msqbuf.msg_perm.gid);
  2014. X    printf("              r/w permission : %d\n", msqbuf.msg_perm.mode);
  2015. X    printf("     number of msgs on queue : %d\n", msqbuf.msg_qnum);
  2016. X    printf("max number of bytes on queue : %d\n", msqbuf.msg_qbytes);
  2017. X    printf("pid of last msgsnd operation : %d\n", msqbuf.msg_lspid);
  2018. X    printf("pid of last msgrcv operation : %d\n", msqbuf.msg_lrpid);
  2019. X    printf("            last msgsnd time : %s", ctime(&msqbuf.msg_stime));
  2020. X    printf("            last msgrcv time : %s", ctime(&msqbuf.msg_rtime));
  2021. X    printf("            last change time : %s", ctime(&msqbuf.msg_ctime));
  2022. X    return(0);
  2023. X} /* msq_display_status */
  2024. X
  2025. X/******************************************************************************
  2026. X * msq_get_status()                                                           *
  2027. X *                                                                            *
  2028. X * Places the current value of each member of the data structure associated   *
  2029. X * with 'msqid' into the structure pointed to by 'msqbuf'.                    *
  2030. X *                                                                            *
  2031. X * Return values: 0 = success / -1 = error                                    *
  2032. X ******************************************************************************/
  2033. Xstatic int
  2034. Xmsq_get_status(msqid, msqbuf)
  2035. Xint msqid;
  2036. Xstruct msqid_ds *msqbuf;
  2037. X{
  2038. X#ifdef DEBUG_MSG
  2039. X    puts("[msg] ***** msq_get_status()");
  2040. X    printf("[msg] params: msqid = %d, msqbuf = %d\n", msqid, msqbuf);
  2041. X#endif /* DEBUG_MSG /**/
  2042. X    return(msgctl(msqid, IPC_STAT, msqbuf));
  2043. X} /* msq_get_status */
  2044. X
  2045. X/******************************************************************************
  2046. X * create_sem()                                                               *
  2047. X *                                                                            *
  2048. X * Creates a semaphore identifier and an associated data structure.           *
  2049. X *                                                                            *
  2050. X * Return values: new semid = success / -1 = error                            *
  2051. X ******************************************************************************/
  2052. Xstatic int
  2053. Xcreate_sem()
  2054. X{
  2055. X#ifdef DEBUG_MSG
  2056. X    puts("[msg] ***** create_sem()");
  2057. X#endif /* DEBUG_MSG /**/
  2058. X    return(semget((key_t) IPC_PRIVATE, 1, IPC_CREAT | SEM_PERMISSION));
  2059. X} /* create_sem */
  2060. X
  2061. X/******************************************************************************
  2062. X * remove_sem()                                                               *
  2063. X *                                                                            *
  2064. X * Removes the semaphore identifier specified by 'semid' from the system and  *
  2065. X * destroys the data structure accosiated with it.                            *
  2066. X *                                                                            *
  2067. X * Return values: 0 = success / -1 = error                                    *
  2068. X ******************************************************************************/
  2069. Xstatic int
  2070. Xremove_sem(semid)
  2071. Xint semid;
  2072. X{
  2073. X    char dummy;
  2074. X
  2075. X#ifdef DEBUG_MSG
  2076. X    puts("[msg] ***** remove_sem()");
  2077. X    printf("[msg] params: semid = %d\n", semid);
  2078. X#endif /* DEBUG_MSG /**/
  2079. X    return(semctl(semid, 0, IPC_RMID, &dummy));
  2080. X} /* remove_sem */
  2081. X
  2082. X/******************************************************************************
  2083. X * sem_get_val()                                                              *
  2084. X *                                                                            *
  2085. X * Gets the value of the semaphore 'semid'.                                   *
  2086. X *                                                                            *
  2087. X * Return values: semaphore value = success / -1 = error                      *
  2088. X ******************************************************************************/
  2089. Xstatic int
  2090. Xsem_get_val(semid)
  2091. Xint semid;
  2092. X{
  2093. X    static union semun arg;
  2094. X
  2095. X#ifdef DEBUG_MSG
  2096. X    puts("[msg] ***** sem_get_val()");
  2097. X    printf("[msg] params: semid = %d\n", semid);
  2098. X#endif /* DEBUG_MSG /**/
  2099. X    return(semctl(semid, 0, GETVAL, arg));
  2100. X} /* sem_get_val */
  2101. X
  2102. X/******************************************************************************
  2103. X * sem_set_val()                                                              *
  2104. X *                                                                            *
  2105. X * Sets the value of the semaphore 'semid' to 'value'.                        *
  2106. X *                                                                            *
  2107. X * Return values: 0 = success / -1 = error                                    *
  2108. X ******************************************************************************/
  2109. Xstatic int
  2110. Xsem_set_val(semid, value)
  2111. Xint semid, value;
  2112. X{
  2113. X    static union semun arg;
  2114. X
  2115. X#ifdef DEBUG_MSG
  2116. X    puts("[msg] ***** sem_set_val()");
  2117. X    printf("[msg] params: semid = %d, value = %d\n", semid, value);
  2118. X#endif /* DEBUG_MSG /**/
  2119. X    arg.val = value;
  2120. X    return(semctl(semid, 0, SETVAL, arg));
  2121. X} /* sem_set_val */
  2122. X
  2123. X/******************************************************************************
  2124. X * sem_set_permission()                                                       *
  2125. X *                                                                            *
  2126. X * Sets the value of the following members of the data structure associated   *
  2127. X * with 'semid' into the structure pointed to by 'buf':                       *
  2128. X * sem_perm.uid, sem_perm.gid, sem_perm.mode                                  *
  2129. X *                                                                            *
  2130. X * Return values: 0 = success / -1 = error                                    *
  2131. X ******************************************************************************/
  2132. Xstatic int
  2133. Xsem_set_permission(semid, uid, gid, mode)
  2134. Xint semid;
  2135. Xushort uid, gid, mode;
  2136. X{
  2137. X    int result;
  2138. X    static union semun arg;
  2139. X
  2140. X#ifdef DEBUG_MSG
  2141. X    puts("[msg] ***** sem_set_permission()");
  2142. X    printf("[msg] params: semid = %d, uid = %d, gid = %d, mode = %d\n", 
  2143. X        semid, uid, gid, mode);
  2144. X#endif /* DEBUG_MSG /**/
  2145. X    arg.buf = (struct semid_ds *) malloc(sizeof(struct semid_ds));
  2146. X    if (arg.buf == NULL) 
  2147. X        return(-1);
  2148. X    arg.buf->sem_perm.uid  = uid;
  2149. X    arg.buf->sem_perm.gid  = gid;
  2150. X    arg.buf->sem_perm.mode = mode;
  2151. X    result = semctl(semid, 0, IPC_SET, arg);
  2152. X    free(arg.buf);
  2153. X    return(result);
  2154. X} /* sem_set_permission */
  2155. X
  2156. X/******************************************************************************
  2157. X * sem_display_status()                                                       *
  2158. X *                                                                            *
  2159. X * Displays the current value of each member of the data structure associated *
  2160. X * with the semaphore specified by 'msqid'.                                   *
  2161. X *                                                                            *
  2162. X * Return values: 0 = success / -1 = error                                    *
  2163. X ******************************************************************************/
  2164. Xstatic int
  2165. Xsem_display_status(semid)
  2166. Xint semid;
  2167. X{
  2168. X    static union semun arg;
  2169. X
  2170. X#ifdef DEBUG_MSG
  2171. X    puts("[msg] ***** sem_display_status()");
  2172. X    printf("[msg] params: semid = %d\n", semid);
  2173. X#endif /* DEBUG_MSG /**/
  2174. X    arg.buf = (struct semid_ds *) malloc(sizeof(struct semid_ds));
  2175. X    if (arg.buf == NULL) 
  2176. X        return(-1);
  2177. X    printf("Values associated to semaphore identifier '%d':\n", semid); 
  2178. X    if (sem_get_status(semid, arg) == -1) {
  2179. X        free(arg.buf);
  2180. X        return(-1);
  2181. X    }
  2182. X    printf("      creator user id : %d\n", arg.buf->sem_perm.cuid);
  2183. X    printf("     creator group id : %d\n", arg.buf->sem_perm.cgid);
  2184. X    printf("              user id : %d\n", arg.buf->sem_perm.uid);
  2185. X    printf("             group id : %d\n", arg.buf->sem_perm.gid);
  2186. X    printf("       r/w permission : %d\n", arg.buf->sem_perm.mode);
  2187. X    printf("number of sems in set : %d\n", arg.buf->sem_nsems);
  2188. X    printf("  last operation time : %s", ctime(&arg.buf->sem_otime));
  2189. X    printf("     last change time : %s", ctime(&arg.buf->sem_ctime));
  2190. X    free(arg.buf);
  2191. X    return(0);
  2192. X} /* sem_display_status */
  2193. X
  2194. X/******************************************************************************
  2195. X * sem_get_status()                                                           *
  2196. X *                                                                            *
  2197. X * Places the current value of each member of the data structure associated   *
  2198. X * with 'semid' into the structure pointed to by 'arg.buf'.                   *
  2199. X *                                                                            *
  2200. X * Return values: 0 = success / -1 = error                                    *
  2201. X ******************************************************************************/
  2202. Xstatic int
  2203. Xsem_get_status(semid, arg)
  2204. Xint semid;
  2205. Xunion semun arg;
  2206. X{
  2207. X#ifdef DEBUG_MSG
  2208. X    puts("[msg] ***** sem_get_status()");
  2209. X    printf("[msg] params: semid = %d, arg = %d\n", semid, arg);
  2210. X#endif /* DEBUG_MSG /**/
  2211. X    return(semctl(semid, 0, IPC_STAT, arg));
  2212. X} /* sem_get_status */
  2213. X
  2214. X/******************************************************************************
  2215. X * _create_port()                                                             *
  2216. X *                                                                            *
  2217. X * Creates a new communication endpoint.                                      *
  2218. X *                                                                            *
  2219. X * Return values: OK = success / ERROR = error                                *
  2220. X ******************************************************************************/
  2221. Xint
  2222. X_create_port(port)
  2223. XPORTDESCR *port;
  2224. X{
  2225. X#ifdef DEBUG_IPC
  2226. X    if (_debug_ipc) {
  2227. X        fprintf(_debugout, "[ipc] %s ***** _create_port():\n", _processprefix);
  2228. X        fprintf(_debugout, "[ipc] %s &port = %d\n", _processprefix, port);
  2229. X    }
  2230. X#endif /* DEBUG_IPC /**/
  2231. X    /* set Errno */
  2232. X    Errno = ECREATEPORT;
  2233. X    /* create a new message queue */
  2234. X    DEBUGPUTS("creating message queue");
  2235. X    if ((port->msqid = create_msq()) < 0) {
  2236. X        DEBUGDISPERR("can't create a new message queue");
  2237. X        return(ERROR);
  2238. X    }
  2239. X    /* create a new semaphore */
  2240. X    DEBUGPUTS("creating semaphore");
  2241. X    if ((port->semid = create_sem()) < 0) {
  2242. X        DEBUGDISPERR("can't create a new semaphore");
  2243. X        return(ERROR);
  2244. X    }
  2245. X    /* initialize semaphore as locked */
  2246. X    DEBUGPUTS("initializing semaphore as locked");
  2247. X    if (sem_set_val(port->semid, LOCKED) < 0) {
  2248. X        DEBUGDISPERR("can't initialize sempahore");
  2249. X        return(ERROR);
  2250. X    }
  2251. X    return(OK);
  2252. X} /* _create_port */
  2253. X
  2254. X/******************************************************************************
  2255. X * _delete_port()                                                             *
  2256. X *                                                                            *
  2257. X * Deletes the communication endpoint specified by 'port'.                    *
  2258. X *                                                                            *
  2259. X * Return values: OK = success / ERROR = error                                * 
  2260. X ******************************************************************************/
  2261. Xint
  2262. X_delete_port(port)
  2263. XPORTDESCR *port;
  2264. X{
  2265. X#ifdef DEBUG_IPC
  2266. X    if (_debug_ipc) {
  2267. X        fprintf(_debugout, "[ipc] %s ***** _delete_port():\n", _processprefix);
  2268. X        _display_port_info("[ipc]", "port", *port);
  2269. X    }
  2270. X#endif /* DEBUG_IPC /**/
  2271. X    /* set Errno */
  2272. X    Errno = EDELETEPORT;
  2273. X    /* remove message queue and semaphore */
  2274. X    DEBUGPUTS("removing message queue and semaphore");
  2275. X    if (remove_msq(port->msqid) || remove_sem(port->semid)) {
  2276. X        DEBUGDISPERR("can't remove message queue or semaphore");
  2277. X        return(ERROR);
  2278. X    }
  2279. X    return(OK);
  2280. X} /* _delete_port */
  2281. X
  2282. X/******************************************************************************
  2283. X * _accept_connection()                                                       *
  2284. X *                                                                            *
  2285. X * Communication endpoint 'port' waits 'time' real time seconds for a         *
  2286. X * connection request (if 'time' equals 0 then the operation is unlimited!).  *
  2287. X *                                                                            *
  2288. X * Return values: OK = success / ERROR = error                                *
  2289. X ******************************************************************************/
  2290. Xint
  2291. X_accept_connection(con_port, port, time)
  2292. XCONNECTIONDESCR *con_port;
  2293. XPORTDESCR       *port;
  2294. Xunsigned         time;
  2295. X{
  2296. X    register int           i;
  2297. X    int                    rcv_msqid;
  2298. X    static struct msgbuf   msgp;
  2299. X    static struct msqid_ds msqbuf;
  2300. X    static struct sembuf   sops;
  2301. X    static PORTDESCR       snd_port;
  2302. X
  2303. X#ifdef DEBUG_IPC
  2304. X    if (_debug_ipc) {
  2305. X        fprintf(_debugout, "[ipc] %s ***** _accept_connection():\n",
  2306. X        _processprefix);
  2307. X        fprintf(_debugout, "[ipc] %s &con_port = %d\n", _processprefix, 
  2308. X        con_port);
  2309. X        _display_port_info("[ipc]", "port", *port);
  2310. X        fprintf(_debugout, "[ipc] %s time = %d\n", _processprefix, time);
  2311. X    }
  2312. X#endif /* DEBUG_IPC /**/
  2313. X    /* set Errno */
  2314. X    Errno = EACPTCON;
  2315. X    /* set timer, if time equals 0 clear timer */
  2316. X    SETTIMER(time);
  2317. X    /* try to get a connection request message */
  2318. X    do {
  2319. X        /* unlock port! */  
  2320. X    DEBUGPUTS("unlocking port");
  2321. X    sops.sem_num = 0;
  2322. X    sops.sem_op  = 1;
  2323. X    sops.sem_flg = 0;
  2324. X    if (semop(port->semid, &sops, 1)) {
  2325. X            DEBUGDISPERR("can't unlock port");
  2326. X            return(ERROR);
  2327. X    }
  2328. X        /* get first message of own message queue */
  2329. X    DEBUGPUTS("receiving request");
  2330. X        if (time == 0) {
  2331. X            if (msgrcv(port->msqid,&msgp,sizeof(PORTDESCR),(long) 0,0) < 0) {
  2332. X            sops.sem_num = 0;
  2333. X            sops.sem_op  = -1;
  2334. X            sops.sem_flg = 0;
  2335. X            if (semop(port->semid, &sops, 1)) {
  2336. X                    DEBUGDISPERR("can't do semaphore operation");
  2337. X                    return(ERROR);
  2338. X                }
  2339. X            DEBUGPUTS("port locked");
  2340. X                DEBUGDISPERR("can't receive request message");
  2341. X                return(ERROR);
  2342. X            }
  2343. X        } else {
  2344. X            do {
  2345. X        if (timeout) {
  2346. X                sops.sem_num = 0;
  2347. X                sops.sem_op  = -1;
  2348. X                sops.sem_flg = 0;
  2349. X                if (semop(port->semid, &sops, 1)) {
  2350. X                        DEBUGDISPERR("can't do semaphore operation");
  2351. X                        return(ERROR);
  2352. X                    }
  2353. X                DEBUGPUTS("port unlocked");
  2354. X        }
  2355. X                RETURN_IF_TIMEOUT;
  2356. X            } while(msgrcv(port->msqid,&msgp,sizeof(PORTDESCR),(long) 0,0) < 0);
  2357. X        }
  2358. X    DEBUGPUTS("port locked");
  2359. X    } while(msgp.mtype != CONNECTION_REQUEST);
  2360. X    /* connection established. Now initialize con_port! */
  2361. X    (void) memcpy(&snd_port, msgp.mtext, sizeof(PORTDESCR));
  2362. X    con_port->own_port.msqid   = port->msqid;
  2363. X    con_port->own_port.semid   = port->semid;
  2364. X    con_port->other_port.msqid = snd_port.msqid;
  2365. X    con_port->other_port.semid = snd_port.semid;
  2366. X#ifdef DEBUG_IPC
  2367. X    if (_debug_ipc) {
  2368. X        fprintf(_debugout, "[ipc] %s got a connection\n", _processprefix);
  2369. X        _display_connection_port_info("[ipc]", "con_port", *con_port);
  2370. X    }
  2371. X#endif /* DEBUG_IPC /**/
  2372. X    /* clear own message queue and send connection refused messages to
  2373. X     * all other connection requesters
  2374. X     */
  2375. X    DEBUGPUTS("clearing own message queue!");
  2376. X    if (msq_get_status(port->msqid, &msqbuf)) {
  2377. X        DEBUGDISPERR("can't get status of message queue");
  2378. X        return(ERROR);
  2379. X    }
  2380. X    for (i=1; i<=msqbuf.msg_qnum; i++) {
  2381. X        if (msgrcv(port->msqid, &msgp, MAXMSGSIZE, (long) 0, 0) < 0) {
  2382. X            DEBUGDISPERR("can't delete useless message");
  2383. X            return(ERROR);
  2384. X        }
  2385. X        /* only connection requests are of interest! */
  2386. X        if (msgp.mtype != CONNECTION_REQUEST)
  2387. X            continue;
  2388. X        /* determine sender */
  2389. X        (void) memcpy(&snd_port, msgp.mtext, sizeof(PORTDESCR));
  2390. X        rcv_msqid = snd_port.msqid;
  2391. X#ifdef DEBUG_IPC
  2392. X    if (_debug_ipc)
  2393. X            fprintf(_debugout, "[ipc] connection to port (msqid = %d, semid = %d) refused\n",
  2394. X                snd_port.msqid, snd_port.semid);
  2395. X#endif /* DEBUG_IPC /**/
  2396. X        /* send reply message to refused requester */
  2397. X        msgp.mtype = CONNECTION_REFUSED;
  2398. X        snd_port.msqid = port->msqid;
  2399. X        snd_port.semid = port->semid;
  2400. X        (void) memcpy(msgp.mtext, &snd_port, sizeof(PORTDESCR));    
  2401. X        if (msgsnd(rcv_msqid, &msgp, sizeof(PORTDESCR), 0)) {
  2402. X            DEBUGDISPERR("can't send >>connection refused<< message");
  2403. X            return(ERROR);
  2404. X        }
  2405. X    } /* for */
  2406. X    DEBUGPUTS("sending reply");
  2407. X    /* send reply message to accepted connection requester */
  2408. X    msgp.mtype = CONNECTION_ACCEPTED;
  2409. X    snd_port.msqid = port->msqid;
  2410. X    snd_port.semid = port->semid;
  2411. X    (void) memcpy(msgp.mtext, &snd_port, sizeof(PORTDESCR));    
  2412. X    if (time == 0) {
  2413. X        if (msgsnd(con_port->other_port.msqid,&msgp,sizeof(PORTDESCR),0)) {
  2414. X            DEBUGDISPERR("can't send reply message");
  2415. X            return(ERROR);
  2416. X        }
  2417. X    } else {
  2418. X        do {
  2419. X            RETURN_IF_TIMEOUT;
  2420. X        } while(msgsnd(con_port->other_port.msqid,&msgp,sizeof(PORTDESCR),0)<0);
  2421. X    }
  2422. X    /* clear timer and return */
  2423. X    (void) alarm(0);
  2424. X    DEBUGPUTS("connection accepted");
  2425. X    return(OK);
  2426. X} /* _accept_connection */
  2427. X
  2428. X/******************************************************************************
  2429. X * _make_connection()                                                         *
  2430. X *                                                                            *
  2431. X * Communication endpoint 'port1' tries 'time' real time seconds to connect   *
  2432. X * to 'port2' (if 'time' equals 0 then the operation is unlimited!).          *
  2433. X *                                                                            *
  2434. X * Return values: OK = success / ERROR = error                                *
  2435. X ******************************************************************************/
  2436. Xint
  2437. X_make_connection(con_port, port1, port2, time)
  2438. XCONNECTIONDESCR *con_port;
  2439. XPORTDESCR       *port1;
  2440. XPORTDESCR       *port2;
  2441. Xunsigned         time;
  2442. X{
  2443. X    static struct msgbuf msgp;
  2444. X    static struct sembuf sops;
  2445. X    static PORTDESCR     snd_port;
  2446. X
  2447. X#ifdef DEBUG_IPC
  2448. X    if (_debug_ipc) {
  2449. X        fprintf(_debugout, "[ipc] %s ***** _make_connection():\n",
  2450. X        _processprefix);
  2451. X        fprintf(_debugout, "[ipc] %s &con_port = %d\n", _processprefix, 
  2452. X        con_port);
  2453. X        _display_port_info("[ipc]", "port1", *port1);
  2454. X        _display_port_info("[ipc]", "port2", *port2);
  2455. X        fprintf(_debugout, "[ipc] %s time = %d\n", _processprefix, time); 
  2456. X    }
  2457. X#endif /* DEBUG_IPC /**/
  2458. X    /* Set Errno */
  2459. X    Errno = EMAKECON;
  2460. X    /* set timer, if time equals 0 clear timer */
  2461. X    SETTIMER(time);
  2462. X    /* initialize request message */
  2463. X    msgp.mtype = CONNECTION_REQUEST;
  2464. X    snd_port.msqid = port1->msqid;
  2465. X    snd_port.semid = port1->semid;
  2466. X    (void) memcpy(msgp.mtext, &snd_port, sizeof(PORTDESCR));
  2467. X    while(!timeout) {
  2468. X        if (time == 0) {
  2469. X            /*
  2470. X             * without time limit!
  2471. X             */
  2472. X            /* wait as long as other port is locked */
  2473. X        sops.sem_num = 0;
  2474. X        sops.sem_op  = -1;
  2475. X        sops.sem_flg = 0;
  2476. X        if (semop(port2->semid, &sops, 1)) {
  2477. X                DEBUGDISPERR("can't do semaphore operation");
  2478. X                return(ERROR);
  2479. X            }
  2480. X        DEBUGPUTS("port unlocked");
  2481. X            /* send request message */
  2482. X        DEBUGPUTS("sending request");
  2483. X            if (msgsnd(port2->msqid, &msgp, sizeof(PORTDESCR), 0)) {
  2484. X                DEBUGDISPERR("can't send request message");
  2485. X                return(ERROR);
  2486. X            }
  2487. X            /* wait for reply message */
  2488. X        DEBUGPUTS("receiving reply");
  2489. X            if (msgrcv(port1->msqid, &msgp, sizeof(PORTDESCR), (long) 0,0) < 0){
  2490. X                DEBUGDISPERR("can't receive reply message");
  2491. X                return(ERROR);
  2492. X            }
  2493. X        } else {
  2494. X            /*
  2495. X             * with time limit!
  2496. X             */
  2497. X            /* wait as long as other port is locked */
  2498. X        sops.sem_num = 0;
  2499. X        sops.sem_op  = -1;
  2500. X        sops.sem_flg = 0;
  2501. X        if (semop(port2->semid, &sops, 1)) {
  2502. X        if (errno == EINTR && timeout) {
  2503. X            Errno = ETIMEOUT;
  2504. X            DEBUGPUTS("TIMEOUT");
  2505. X        } else
  2506. X                    DEBUGDISPERR("can't do semaphore operation");
  2507. X                return(ERROR);
  2508. X            }
  2509. X        DEBUGPUTS("port unlocked");
  2510. X            /* send request message */
  2511. X        DEBUGPUTS("sending request");
  2512. X            do {
  2513. X                RETURN_IF_TIMEOUT;
  2514. X            } while(msgsnd(port2->msqid, &msgp, sizeof(PORTDESCR), 0) < 0);
  2515. X            /* wait for reply message */
  2516. X        DEBUGPUTS("receiving reply");
  2517. X            do {
  2518. X                RETURN_IF_TIMEOUT;
  2519. X            } while(msgrcv(port1->msqid,&msgp,sizeof(PORTDESCR),(long)0,0) < 0);
  2520. X        }
  2521. X        switch(msgp.mtype) {
  2522. X        case CONNECTION_ACCEPTED:
  2523. X            con_port->own_port.msqid   = port1->msqid;    
  2524. X            con_port->own_port.semid   = port1->semid;    
  2525. X            con_port->other_port.msqid = port2->msqid;    
  2526. X            con_port->other_port.semid = port2->semid;    
  2527. X        mcon_retry_delay = MCON_RETRY_DELAY_MIN;
  2528. X#ifdef DEBUG_IPC
  2529. X        if (_debug_ipc) {
  2530. X            fprintf(_debugout, "[ipc] %s connection established\n",
  2531. X            _processprefix);
  2532. X            _display_connection_port_info("[ipc]", "con_port", *con_port);
  2533. X                fprintf(_debugout, "[ipc] %s retry delay now %d\n",
  2534. X                    _processprefix, mcon_retry_delay);
  2535. X                if (_debugflush)
  2536. X                    fflush(_debugout);
  2537. X            }
  2538. X#endif /* DEBUG_IPC /**/
  2539. X            /* clear timer and return */
  2540. X            (void) alarm(0);
  2541. X            return(OK);
  2542. X            /* break; */
  2543. X    case CONNECTION_REQUEST:
  2544. X        case CONNECTION_REFUSED:
  2545. X        if (msgp.mtype == CONNECTION_REFUSED) {
  2546. X            DEBUGPUTS("connection refused");
  2547. X        } else {
  2548. X            DEBUGPUTS("wrong reply message");
  2549. X        }
  2550. X        nap(mcon_retry_delay);
  2551. X        if (mcon_retry_delay < MCON_RETRY_DELAY_MAX)
  2552. X        mcon_retry_delay += MCON_RETRY_DELAY_STEP;
  2553. X#ifdef DEBUG_IPC
  2554. X            if (_debug_ipc) {
  2555. X                fprintf(_debugout, "[ipc] %s retry delay now %d\n",
  2556. X                    _processprefix, mcon_retry_delay);
  2557. X                if (_debugflush)
  2558. X                    fflush(_debugout);
  2559. X            }
  2560. X#endif /* DEBUG_IPC /**/
  2561. X        DEBUGPUTS("trying again");
  2562. X            continue;
  2563. X            /* break; */
  2564. X        default:
  2565. X        DEBUGPUTS("unknown reply message");
  2566. X        errno = 0;
  2567. X            Errno = EFATAL;
  2568. X            return(ERROR);
  2569. X        } /* switch */
  2570. X    } /* while */
  2571. X    DEBUGPUTS("TIMEOUT");
  2572. X    mcon_retry_delay = MCON_RETRY_DELAY_MIN;
  2573. X#ifdef DEBUG_IPC
  2574. X    if (_debug_ipc) {
  2575. X        fprintf(_debugout, "[ipc] %s retry delay now %d\n",
  2576. X            _processprefix, mcon_retry_delay);
  2577. X        if (_debugflush)
  2578. X            fflush(_debugout);
  2579. X    }
  2580. X#endif /* DEBUG_IPC /**/
  2581. X    Errno = ETIMEOUT;
  2582. X    return(ERROR);
  2583. X} /* _make_connection */
  2584. X
  2585. X/******************************************************************************
  2586. X * _close_connection()                                                        *
  2587. X *                                                                            *
  2588. X * The connection associated to connection port 'con_port' is closed.         *
  2589. X *                                                                            *
  2590. X * Return values: OK = success / ERROR = error                                *
  2591. X ******************************************************************************/
  2592. Xint
  2593. X_close_connection(con_port)
  2594. XCONNECTIONDESCR *con_port;
  2595. X{
  2596. X    register int           i;
  2597. X    static struct msqid_ds msqbuf;
  2598. X    static struct msgbuf   msgp;
  2599. X
  2600. X#ifdef DEBUG_IPC
  2601. X    if (_debug_ipc) {
  2602. X        fprintf(_debugout, "[ipc] %s ***** _close_connection():\n",
  2603. X        _processprefix);
  2604. X        _display_connection_port_info("[ipc]", "con_port", *con_port);
  2605. X    }
  2606. X#endif /* DEBUG_IPC /**/
  2607. X    /* Set Errno */
  2608. X    Errno = ECLOSECON;
  2609. X    /* delete all messages of own message queue */
  2610. X    if (msq_get_status(con_port->own_port.msqid, &msqbuf)) {
  2611. X        DEBUGDISPERR("can't get status of message queue");
  2612. X        return(ERROR);
  2613. X    }
  2614. X#ifdef DEBUG_IPC
  2615. X    if (_debug_ipc) 
  2616. X        fprintf(_debugout, "[ipc] %s deleting %d messages\n", _processprefix,
  2617. X        msqbuf.msg_qnum);
  2618. X#endif
  2619. X    for (i=1; i<=msqbuf.msg_qnum; i++) {
  2620. X        if (msgrcv(con_port->own_port.msqid,&msgp,MAXMSGSIZE,(long) 0,0) < 0) {
  2621. X            DEBUGDISPERR("can't delete message");
  2622. X            return(ERROR);
  2623. X        }
  2624. X    }
  2625. X    DEBUGPUTS("connection closed");
  2626. X    return(OK);
  2627. X} /* _close_connection */
  2628. X
  2629. X/******************************************************************************
  2630. X * _recv_data()                                                               *
  2631. X *                                                                            *
  2632. X * 'number' bytes are received from connection port 'con_port' and stored     *
  2633. X * into 'buffer'. 'time' is the maximum real time in seconds to wait for a    *
  2634. X * message to arrive (if 'time' equals 0 the waiting is unlimited).           * 
  2635. X *                                                                            *
  2636. X * Return values: number of received bytes upon success / ERROR = error       *
  2637. X ******************************************************************************/
  2638. Xint
  2639. X_recv_data(con_port, buffer, number, time)
  2640. XCONNECTIONDESCR *con_port;
  2641. Xchar            *buffer;
  2642. Xint              number;
  2643. Xunsigned         time;
  2644. X{
  2645. X    int                  bytes;
  2646. X    static struct msgbuf msgp;
  2647. X
  2648. X#ifdef DEBUG_IPC
  2649. X    if (_debug_ipc) {
  2650. X        fprintf(_debugout, "[ipc] %s ***** _recv_data():\n", _processprefix);
  2651. X        _display_connection_port_info("[ipc]", "con_port", *con_port);
  2652. X        fprintf(_debugout, "[ipc] %s buffer = %d, number = %d\n",
  2653. X        _processprefix, buffer, number);
  2654. X        fprintf(_debugout, "[ipc] %s time = %d\n", _processprefix, time);
  2655. X    }
  2656. X#endif /* DEBUG_IPC /**/
  2657. X    /* set Errno */
  2658. X    Errno = ERECVDATA;
  2659. X    /* set timer, if time equals 0 clear timer */
  2660. X    SETTIMER(time);
  2661. X    if (time == 0) {
  2662. X        if ((bytes = msgrcv(con_port->own_port.msqid,&msgp,number,(long) 0,0)) < 0) {
  2663. X            DEBUGDISPERR("can't receive message");
  2664. X            return(ERROR);
  2665. X        }    
  2666. X    } else {
  2667. X        do {
  2668. X            RETURN_IF_TIMEOUT;
  2669. X        } while((bytes = msgrcv(con_port->own_port.msqid,&msgp,number,(long) 0,0)) < 0);
  2670. X    }
  2671. X    /* check for correct sender! */
  2672. X    if (msgp.mtype != con_port->other_port.msqid) {
  2673. X        fputs("Panic: disastrous error in _recv_data(ipc_Xenix.c):\n", stderr);
  2674. X    fputs("       wrong message received!\n", stderr);
  2675. X        fprintf(stderr, "       msgp.mtype = %d, con_port->other_port.msqid = %d\n",
  2676. X            msgp.mtype, con_port->other_port.msqid);
  2677. X        fputs("       stopping program!\n", stderr);
  2678. X    fflush(stderr);
  2679. X    exit(-1);
  2680. X    }
  2681. X    (void) memcpy(buffer, msgp.mtext, bytes);
  2682. X    (void) alarm(0);
  2683. X    return(bytes);
  2684. X} /* _recv_data */
  2685. X
  2686. X/******************************************************************************
  2687. X * _send_data()                                                               *
  2688. X *                                                                            *
  2689. X * 'number' bytes, stored in 'buffer', are send to connection port 'con_port'.*
  2690. X * 'time' is the maximum real time in seconds to retry sending upon error (if *
  2691. X * 'time' equals 0 the waiting is unlimited).                                 *
  2692. X *                                                                            *
  2693. X * Return values: number of sent bytes upon success / ERROR = error           *
  2694. X ******************************************************************************/
  2695. Xint
  2696. X_send_data(con_port, buffer, number, time)
  2697. XCONNECTIONDESCR *con_port;
  2698. Xchar            *buffer;
  2699. Xint              number;
  2700. Xunsigned         time;
  2701. X{
  2702. X    static struct msgbuf msgp;
  2703. X
  2704. X#ifdef DEBUG_IPC
  2705. X    if (_debug_ipc) {
  2706. X        fprintf(_debugout, "[ipc] %s ***** _send_data():\n", _processprefix);
  2707. X        _display_connection_port_info("[ipc]", "con_port", *con_port);
  2708. X        fprintf(_debugout, "[ipc] %s buffer = %d, number = %d\n",
  2709. X        _processprefix, buffer, number);
  2710. X        fprintf(_debugout, "[ipc] %s time = %d\n", _processprefix, time);
  2711. X    }
  2712. X#endif /* DEBUG_IPC /**/
  2713. X    /* set Errno */
  2714. X    Errno = ESENDDATA;
  2715. X    /* set timer, if time equals 0 clear timer */
  2716. X    SETTIMER(time);
  2717. X    /* message type is the own message queue identifier. 
  2718. X     * This is used to verifiy message passing!
  2719. X     */
  2720. X    msgp.mtype = (long) con_port->own_port.msqid;
  2721. X    (void) memcpy(msgp.mtext, buffer, number);
  2722. X    if (time == 0) {
  2723. X        if (msgsnd(con_port->other_port.msqid, &msgp, number, 0)) {
  2724. X            DEBUGDISPERR("can't send message");
  2725. X            return(ERROR);
  2726. X        }
  2727. X    } else {
  2728. X        do {
  2729. X           RETURN_IF_TIMEOUT;
  2730. X        } while(msgsnd(con_port->other_port.msqid, &msgp, number, 0) < 0);
  2731. X    }
  2732. X    (void) alarm(0);
  2733. X    return(number);
  2734. X} /* _send_data */
  2735. X
  2736. X/* ============================= DEBUG Routines ============================= */
  2737. X
  2738. X/******************************************************************************
  2739. X * _display_port_info()                                                       *
  2740. X *                                                                            *
  2741. X * Displays the components of the structure PORTDESCR specified by 'port'.    *
  2742. X *                                                                            *
  2743. X * Return values: always OK for success                                       *
  2744. X ******************************************************************************/
  2745. Xint
  2746. X_display_port_info(prefix, msg, port)
  2747. Xchar *prefix, *msg;
  2748. XPORTDESCR port;
  2749. X{
  2750. X    fprintf(_debugout, "%s %s %s: msqid = %d, semid = %d\n", prefix,
  2751. X    _processprefix, msg, port.msqid, port.semid);
  2752. X    return(OK);
  2753. X} /* _display_port_info */
  2754. X
  2755. X/******************************************************************************
  2756. X * _display_connection_port_info()                                            *
  2757. X *                                                                            *
  2758. X * Displays the components of the structure CONNECTIONDESCR specified by      *
  2759. X * 'con_port'.                                                                *
  2760. X *                                                                            *
  2761. X * Return values: always OK for success                                       *
  2762. X ******************************************************************************/
  2763. Xint
  2764. X_display_connection_port_info(prefix, msg, con_port)
  2765. Xchar *prefix, *msg;
  2766. XCONNECTIONDESCR con_port;
  2767. X{
  2768. X    fprintf(_debugout, "%s %s %s:   own_port: msqid = %d, semid = %d\n", prefix,
  2769. X    _processprefix, msg, con_port.own_port.msqid, con_port.own_port.semid);
  2770. X    fprintf(_debugout, "%s %s %s: other_port: msqid = %d, semid = %d\n", prefix,
  2771. X    _processprefix, msg, con_port.other_port.msqid, 
  2772. X    con_port.other_port.semid);
  2773. X    return(OK);
  2774. X} /* _display_connection_port_info */
  2775. X
  2776. X/******************************************************************************
  2777. X * _input_port_info()                                                         *
  2778. X *                                                                            *
  2779. X * Input the port information for 'port'.                                     *
  2780. X *                                                                            *
  2781. X * Return values: none                                                        *
  2782. X ******************************************************************************/
  2783. Xint
  2784. X_input_port_info(port)
  2785. XPORTDESCR *port;
  2786. X{
  2787. X    printf("msqid = "); 
  2788. X    scanf("%d", &(port->msqid));
  2789. X    printf("semid = "); 
  2790. X    scanf("%d", &(port->semid));
  2791. X} /* _input_port_info */
  2792. END_OF_FILE
  2793. if test 41235 -ne `wc -c <'lib/ipc_msgsem.c'`; then
  2794.     echo shar: \"'lib/ipc_msgsem.c'\" unpacked with wrong size!
  2795. fi
  2796. # end of 'lib/ipc_msgsem.c'
  2797. fi
  2798. echo shar: End of archive 16 \(of 18\).
  2799. cp /dev/null ark16isdone
  2800. MISSING=""
  2801. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  2802.     if test ! -f ark${I}isdone ; then
  2803.     MISSING="${MISSING} ${I}"
  2804.     fi
  2805. done
  2806. if test "${MISSING}" = "" ; then
  2807.     echo You have unpacked all 18 archives.
  2808.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2809. else
  2810.     echo You still need to unpack the following archives:
  2811.     echo "        " ${MISSING}
  2812. fi
  2813. ##  End of shell archive.
  2814. exit 0
  2815.