home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / veos-2.0 / part15 < prev    next >
Encoding:
Text File  |  1993-04-25  |  45.9 KB  |  2,023 lines

  1. Newsgroups: comp.sources.unix
  2. From: voodoo@hitl.washington.edu (Geoffery Coco)
  3. Subject: v26i198: veos-2.0 - The Virtual Environment Operating Shell, V2.0, Part15/16
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: voodoo@hitl.washington.edu (Geoffery Coco)
  8. Posting-Number: Volume 26, Issue 198
  9. Archive-Name: veos-2.0/part15
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 15 (of 16)."
  18. # Contents:  kernel_private/src/shell/xv_glutils.c
  19. # Wrapped by vixie@efficacy.home.vix.com on Sun Apr 25 23:10:47 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'kernel_private/src/shell/xv_glutils.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'kernel_private/src/shell/xv_glutils.c'\"
  23. else
  24. echo shar: Extracting \"'kernel_private/src/shell/xv_glutils.c'\" \(43094 characters\)
  25. sed "s/^X//" >'kernel_private/src/shell/xv_glutils.c' <<'END_OF_FILE'
  26. X/****************************************************************************************
  27. X *                                            *
  28. X * file: xv_glutils.c                                    *
  29. X *                                            *
  30. X * Sundry utilities which serve as glue for xlisp veos primitives.            *
  31. X *                                            *
  32. X * creation: April 13, 1992                                *
  33. X *                                            *
  34. X *                                            *
  35. X * by Geoffrey P. Coco at the HITLab, Seattle.                          *
  36. X *                                            *
  37. X ****************************************************************************************/
  38. X
  39. X
  40. X/****************************************************************************************
  41. X * Copyright (C) 1992  Geoffrey P. Coco, Human Interface Technology Lab, Seattle    *
  42. X ****************************************************************************************/
  43. X
  44. X
  45. X
  46. X/****************************************************************************************
  47. X *                          preliminaries                    */
  48. X
  49. X#include <math.h>
  50. X#include "xlisp.h"
  51. X
  52. X/* VEOS definitions: */
  53. X#include "kernel.h"
  54. X
  55. X#define NATIVE_CODE
  56. X#include "xv_native.h"
  57. X#undef NATIVE_CODE
  58. X
  59. X/****************************************************************************************/
  60. X
  61. Xextern LVAL     xsendmsg0();
  62. Xextern LVAL    s_unbound;
  63. Xextern LVAL    true;
  64. Xextern LVAL     xlfatal();
  65. X
  66. X/****************************************************************************************/
  67. X
  68. Xboolean        native_bSubstBeenMarked;
  69. Xboolean        native_bVoidBeenMarked;
  70. Xboolean        native_bDestruct;
  71. X
  72. X#define SUBST    native_bSubstBeenMarked
  73. X#define VOID    native_bVoidBeenMarked
  74. X#define MOD    native_bDestruct
  75. X
  76. X/****************************************************************************************/
  77. X
  78. XTVeosErr Native_PatVEltClerical();
  79. Xextern LVAL ReverseList();
  80. X
  81. X/****************************************************************************************/
  82. X
  83. X
  84. X
  85. X
  86. X/****************************************************************************************
  87. X                Basic Xlisp <--> Nancy Conversion
  88. X ****************************************************************************************/
  89. X
  90. X
  91. X/****************************************************************************************/
  92. XTVeosErr Native_XEltToVElt(pXElt, pVElt)
  93. X    LVAL     pXElt;
  94. X    TPElt    pVElt;
  95. X{
  96. X    TVeosErr    iErr;
  97. X
  98. X    iErr = VEOS_FAILURE;
  99. X
  100. X
  101. X    /** NIL is the empty grouple **/
  102. X
  103. X    if (null(pXElt)) {
  104. X    iErr = Nancy_NewGrouple(&pVElt->u.pGr);
  105. X    pVElt->iType = GR_grouple;
  106. X    }
  107. X
  108. X
  109. X    /** case-wise conversion to nancy format **/
  110. X
  111. X    else {
  112. X    switch (ntype(pXElt)) {
  113. X
  114. X    case CONS:
  115. X        /** a list becomes a grouple **/
  116. X        iErr = Native_ListToGrouple(pXElt, &pVElt->u.pGr);
  117. X        pVElt->iType = GR_grouple;
  118. X        break;
  119. X        
  120. X    case VECTOR:
  121. X        /** a vector becomes a special grouple **/
  122. X        iErr = Native_VectToGrouple(pXElt, &pVElt->u.pGr);
  123. X        pVElt->iType = GR_vector;
  124. X        break;
  125. X
  126. X    case FIXNUM:
  127. X        pVElt->iType = GR_int;
  128. X        pVElt->u.iVal = getfixnum(pXElt);
  129. X        break;
  130. X        
  131. X    case FLONUM:
  132. X        pVElt->iType = GR_float;
  133. X        pVElt->u.fVal = (float) getflonum(pXElt);
  134. X        break;
  135. X        
  136. X    case STRING:
  137. X        pVElt->iType = GR_string;
  138. X        pVElt->u.pS = strdup((char *) getstring(pXElt));
  139. X        break;
  140. X        
  141. X    case SYMBOL:
  142. X        pVElt->iType = GR_prim;
  143. X        pVElt->u.pS = strdup(getstring(getpname(pXElt)));
  144. X        break;
  145. X        
  146. X    default:
  147. X        iErr = NATIVE_BADVTYPE;
  148. X        break;
  149. X
  150. X        }
  151. X    }
  152. X
  153. X    return(iErr);
  154. X
  155. X    } /* Native_XEltToVElt */
  156. X/****************************************************************************************/
  157. X
  158. X
  159. X
  160. X/****************************************************************************************/
  161. XTVeosErr Native_ListToGrouple(pList, hGrouple)
  162. X    LVAL    pList;
  163. X    THGrouple    hGrouple;
  164. X{
  165. X    TVeosErr    iErr;
  166. X    LVAL    pXFinger;
  167. X    int        iElt;
  168. X    TPGrouple    pGrouple;
  169. X    TPElt    pVFinger;
  170. X
  171. X    
  172. X    *hGrouple = nil;
  173. X
  174. X    iErr = Nancy_NewGrouple(&pGrouple);
  175. X    iElt = 0;
  176. X
  177. X    /** convert each lisp sub-element **/
  178. X
  179. X    pXFinger = pList;
  180. X    while (!null(pXFinger) && iErr == VEOS_SUCCESS) {
  181. X
  182. X
  183. X    /** make room for another grouple element **/
  184. X    
  185. X    Nancy_NewElementsInGrouple(pGrouple, iElt, 1, GR_unspecified, 0);
  186. X
  187. X
  188. X    /** do actual element conversion **/
  189. X
  190. X    iErr = Native_XEltToVElt(car(pXFinger), &pGrouple->pEltList[iElt]);
  191. X
  192. X
  193. X    /** advance element refs **/
  194. X
  195. X    iElt ++;
  196. X    pXFinger = cdr(pXFinger);
  197. X
  198. X    } /* while */
  199. X
  200. X
  201. X    if (iErr == VEOS_SUCCESS)
  202. X    *hGrouple = pGrouple;
  203. X    else
  204. X    Nancy_DisposeGrouple(pGrouple);
  205. X
  206. X
  207. X    return(iErr);
  208. X
  209. X    } /* Native_ListToGrouple */
  210. X/****************************************************************************************/
  211. X
  212. X
  213. X
  214. X/****************************************************************************************/
  215. XTVeosErr Native_VectToGrouple(pVect, hGrouple)
  216. X    LVAL    pVect;
  217. X    THGrouple    hGrouple;
  218. X{
  219. X    TVeosErr    iErr;
  220. X    int        iElts, iEltIndex;
  221. X    TPGrouple    pGrouple;
  222. X    TPElt    pVElt;
  223. X
  224. X    *hGrouple = nil;
  225. X
  226. X    iErr = Nancy_NewGrouple(&pGrouple);
  227. X
  228. X
  229. X    iElts = getsz(pVect);
  230. X    if (iElts > 0 && iErr == VEOS_SUCCESS) {
  231. X
  232. X    /** make enough room for all impending elements **/
  233. X
  234. X    iErr = Nancy_NewElementsInGrouple(pGrouple, 0, iElts, GR_unspecified, 0);
  235. X
  236. X
  237. X
  238. X    /** convert each lisp sub-element **/
  239. X
  240. X    iEltIndex = 0; pVElt = pGrouple->pEltList;
  241. X    while (iEltIndex < iElts && iErr == VEOS_SUCCESS) {
  242. X
  243. X        iErr = Native_XEltToVElt(getelement(pVect, iEltIndex), pVElt);
  244. X
  245. X        iEltIndex ++; pVElt ++;
  246. X        }
  247. X    }
  248. X
  249. X    if (iErr == VEOS_SUCCESS)
  250. X    *hGrouple = pGrouple;
  251. X    else
  252. X    Nancy_DisposeGrouple(pGrouple);
  253. X
  254. X
  255. X    return(iErr);
  256. X
  257. X    } /* Native_VectToGrouple */
  258. X/****************************************************************************************/
  259. X
  260. X
  261. X
  262. X/****************************************************************************************/
  263. XTVeosErr Native_VEltToXElt(pVElt, hXElt)
  264. X    TPElt    pVElt;
  265. X    LVAL     *hXElt;
  266. X{
  267. X    TVeosErr    iErr;
  268. X
  269. X
  270. X    *hXElt = NIL;
  271. X
  272. X    iErr = VEOS_SUCCESS;
  273. X
  274. X    switch (pVElt->iType) {
  275. X
  276. X    case GR_grouple:
  277. X    iErr = Native_GroupleToList(pVElt->u.pGr, hXElt);
  278. X    break;
  279. X    
  280. X    case GR_vector:
  281. X    iErr = Native_GroupleToVect(pVElt->u.pGr, hXElt);
  282. X    break;
  283. X
  284. X    case GR_int:            
  285. X    *hXElt = cvfixnum(pVElt->u.iVal);
  286. X    break;
  287. X    
  288. X    case GR_float:
  289. X    *hXElt = cvflonum(pVElt->u.fVal);
  290. X    break;
  291. X    
  292. X    case GR_string:
  293. X    *hXElt = cvstring(pVElt->u.pS);
  294. X    break;
  295. X    
  296. X    case GR_prim:
  297. X    *hXElt = xlenter(pVElt->u.pS);
  298. X    break;
  299. X
  300. X    case GR_unspecified:
  301. X    iErr = NATIVE_EMPTYELT;
  302. X    break;
  303. X
  304. X    default:    
  305. X    iErr = NATIVE_BADXTYPE;
  306. X    break;
  307. X
  308. X    }
  309. X
  310. X    return(iErr);
  311. X
  312. X    } /* Native_VEltToXElt */
  313. X/****************************************************************************************/
  314. X
  315. X
  316. X
  317. X/****************************************************************************************/
  318. XTVeosErr Native_GroupleToList(pGrouple, hList)
  319. X    TPGrouple    pGrouple;
  320. X    LVAL    *hList;
  321. X{
  322. X    TVeosErr    iErr;
  323. X    LVAL    pNewXElt, pList;
  324. X    int        iElts, iElt;
  325. X
  326. X    xlstkcheck(2);
  327. X    xlsave(pNewXElt);
  328. X    xlsave(pList);
  329. X
  330. X    iErr = VEOS_SUCCESS;
  331. X    iElts = pGrouple->iElts;
  332. X    iElt = iElts - 1;
  333. X
  334. X    while (iElt >= 0 && iErr == VEOS_SUCCESS) {
  335. X    
  336. X    iErr = Native_VEltToXElt(&pGrouple->pEltList[iElt], &pNewXElt);
  337. X    if (iErr == VEOS_SUCCESS)
  338. X        pList = cons(pNewXElt, pList);
  339. X
  340. X    iElt --;
  341. X    }
  342. X
  343. X    *hList = pList;
  344. X
  345. X    xlpopn(2);
  346. X
  347. X    return(iErr);
  348. X
  349. X    } /* Native_GroupleToList */
  350. X/****************************************************************************************/
  351. X
  352. X
  353. X
  354. X/****************************************************************************************/
  355. XTVeosErr Native_GroupleToVect(pGrouple, hVect)
  356. X    TPGrouple    pGrouple;
  357. X    LVAL    *hVect;
  358. X{
  359. X    TVeosErr    iErr;
  360. X    LVAL    pNewXElt, pVect;
  361. X    int        iElts, iElt;
  362. X
  363. X    xlstkcheck(2);
  364. X    xlsave(pVect);
  365. X    xlsave(pNewXElt);
  366. X
  367. X    iErr = VEOS_SUCCESS;
  368. X    iElts = pGrouple->iElts;
  369. X    iElt = 0;
  370. X
  371. X    pVect = newvector(iElts);
  372. X
  373. X    while (iElt < iElts && iErr == VEOS_SUCCESS) {
  374. X    
  375. X    iErr = Native_VEltToXElt(&pGrouple->pEltList[iElt], &pNewXElt);
  376. X    if (iErr == VEOS_SUCCESS)
  377. X        setelement(pVect, iElt, pNewXElt);
  378. X
  379. X    iElt ++;
  380. X    }
  381. X
  382. X    *hVect = pVect;
  383. X
  384. X    xlpopn(2);
  385. X
  386. X    return(iErr);
  387. X
  388. X    } /* Native_GroupleToVect */
  389. X/****************************************************************************************/
  390. X
  391. X
  392. X
  393. X/****************************************************************************************
  394. X             Timestamped Xlisp <--> Nancy Conversion
  395. X ****************************************************************************************/
  396. X
  397. X/****************************************************************************************/
  398. XTVeosErr Native_NewVEltToXElt(pVElt, hXElt, time)
  399. X    TPElt    pVElt;
  400. X    LVAL     *hXElt;
  401. X    TTimeStamp    time;
  402. X{
  403. X    TVeosErr    iErr;
  404. X
  405. X    *hXElt = NIL;
  406. X    iErr = NATIVE_STALE;
  407. X
  408. X    if (TIME_LESS_THAN(pVElt->tLastMod, time)) {
  409. X
  410. X    /** old data, retrieve only contents of containers 
  411. X     **/
  412. X    if (pVElt->iType == GR_grouple)
  413. X        iErr = Native_NewGroupleToList(pVElt->u.pGr, hXElt, time);
  414. X    
  415. X    else if (pVElt->iType == GR_vector)
  416. X        iErr = Native_NewGroupleToVect(pVElt->u.pGr, hXElt, time);
  417. X    }
  418. X
  419. X    else {
  420. X    /** new data, retrieve completely **/
  421. X
  422. X    switch (pVElt->iType) {
  423. X        
  424. X    case GR_grouple:            
  425. X        iErr = Native_GroupleToList(pVElt->u.pGr, hXElt);
  426. X        break;
  427. X
  428. X    case GR_vector:            
  429. X        iErr = Native_GroupleToVect(pVElt->u.pGr, hXElt);
  430. X        break;
  431. X
  432. X    case GR_int:            
  433. X        *hXElt = cvfixnum(pVElt->u.iVal);
  434. X        iErr = VEOS_SUCCESS;
  435. X        break;
  436. X        
  437. X    case GR_float:
  438. X        *hXElt = cvflonum(pVElt->u.fVal);
  439. X        iErr = VEOS_SUCCESS;
  440. X        break;
  441. X        
  442. X    case GR_string:
  443. X        *hXElt = cvstring(pVElt->u.pS);
  444. X        iErr = VEOS_SUCCESS;
  445. X        break;
  446. X        
  447. X    case GR_prim:
  448. X        *hXElt = xlenter(pVElt->u.pS);
  449. X        iErr = VEOS_SUCCESS;
  450. X        break;
  451. X        
  452. X    case GR_unspecified:
  453. X        iErr = NATIVE_EMPTYELT;
  454. X        break;
  455. X        
  456. X    default:    
  457. X        iErr = NATIVE_BADXTYPE;
  458. X        break;
  459. X        
  460. X        }
  461. X    }
  462. X
  463. X    return(iErr);
  464. X
  465. X    } /* Native_NewVEltToXElt */
  466. X/****************************************************************************************/
  467. X
  468. X
  469. X
  470. X/****************************************************************************************/
  471. XTVeosErr Native_NewGroupleToList(pGrouple, hList, time)
  472. X    TPGrouple    pGrouple;
  473. X    LVAL    *hList;
  474. X    TTimeStamp    time;
  475. X{
  476. X    TVeosErr    iErr = VEOS_SUCCESS;
  477. X    LVAL    pNewXElt, pList;
  478. X    int        iElts, iElt;
  479. X    TPElt    pVElt;
  480. X    boolean    bStale = TRUE;
  481. X
  482. X    xlsave1(pNewXElt);
  483. X    xlsave1(pList);
  484. X
  485. X    iElts = pGrouple->iElts;
  486. X    iElt = iElts - 1;
  487. X
  488. X    while (iElt >= 0) {
  489. X    
  490. X    /** determine if caller has already seen this data **/
  491. X    
  492. X    iErr = Native_NewVEltToXElt(&pGrouple->pEltList[iElt], &pNewXElt, time);
  493. X    if (iErr == VEOS_SUCCESS) {
  494. X        /** assume caller has locked this ptr **/
  495. X
  496. X        pList = cons(pNewXElt, pList);
  497. X        bStale = FALSE;
  498. X        }
  499. X
  500. X    else if (iErr == NATIVE_STALE)
  501. X        iErr = VEOS_SUCCESS;
  502. X
  503. X    else
  504. X        break;
  505. X
  506. X    iElt --;
  507. X    }
  508. X
  509. X    if (iErr == VEOS_SUCCESS) {
  510. X    if (bStale)
  511. X        iErr = NATIVE_STALE;
  512. X
  513. X    *hList = pList;
  514. X    }
  515. X
  516. X    xlpopn(2);
  517. X
  518. X    return(iErr);
  519. X
  520. X    } /* Native_NewGroupleToList */
  521. X/****************************************************************************************/
  522. X
  523. X
  524. X
  525. X/****************************************************************************************/
  526. XTVeosErr Native_NewGroupleToVect(pGrouple, hVect, time)
  527. X    TPGrouple    pGrouple;
  528. X    LVAL    *hVect;
  529. X    TTimeStamp    time;
  530. X{
  531. X    TVeosErr    iErr = VEOS_SUCCESS;
  532. X    LVAL    pNewXElt, pVect;
  533. X    int        iElts, iElt;
  534. X    boolean    bStale = TRUE;
  535. X
  536. X    xlsave1(pNewXElt);
  537. X    xlsave1(pVect);
  538. X
  539. X    iElts = pGrouple->iElts;
  540. X    pVect = newvector(iElts);
  541. X
  542. X    iElt = 0;
  543. X
  544. X    while (iElt < iElts) {
  545. X    
  546. X    iErr = Native_NewVEltToXElt(&pGrouple->pEltList[iElt], &pNewXElt, time);
  547. X    if (iErr == VEOS_SUCCESS) {
  548. X
  549. X        /** assume caller has locked this ptr **/
  550. X
  551. X        setelement(pVect, iElt, pNewXElt);
  552. X        bStale = FALSE;
  553. X        }
  554. X
  555. X    else if (iErr == NATIVE_STALE)
  556. X        iErr = VEOS_SUCCESS;
  557. X
  558. X    else
  559. X        break;
  560. X
  561. X    iElt ++;
  562. X    }
  563. X
  564. X    if (iErr == VEOS_SUCCESS) {
  565. X    if (bStale)
  566. X        iErr = NATIVE_STALE;
  567. X    
  568. X    *hVect = pVect;
  569. X    }
  570. X
  571. X    xlpopn(2);
  572. X
  573. X    return(iErr);
  574. X
  575. X    } /* Native_NewGroupleToVect */
  576. X/****************************************************************************************/
  577. X
  578. X
  579. X
  580. X/****************************************************************************************/
  581. XTVeosErr Native_XEltToNewVElt(pXElt, pVElt, time)
  582. X    LVAL     pXElt;
  583. X    TPElt    pVElt;
  584. X    TTimeStamp    time;
  585. X{
  586. X    TVeosErr    iErr;
  587. X
  588. X    iErr = VEOS_SUCCESS;
  589. X
  590. X
  591. X    /** NIL is the empty grouple **/
  592. X
  593. X    if (null(pXElt)) {
  594. X    pVElt->iType = GR_grouple;
  595. X    iErr = Nancy_NewGrouple(&pVElt->u.pGr);
  596. X    }
  597. X
  598. X    /** case-wise conversion to nancy format **/
  599. X
  600. X    else {
  601. X    switch (ntype(pXElt)) {
  602. X
  603. X    case CONS:
  604. X        /** a list becomes a grouple **/
  605. X        iErr = Native_ListToNewGrouple(pXElt, &pVElt->u.pGr, time);
  606. X        pVElt->iType = GR_grouple;
  607. X        break;
  608. X        
  609. X    case VECTOR:
  610. X        /** a vector becomes a special grouple **/
  611. X        iErr = Native_VectToNewGrouple(pXElt, &pVElt->u.pGr, time);
  612. X        pVElt->iType = GR_vector;
  613. X        break;
  614. X
  615. X    case FIXNUM:
  616. X        pVElt->iType = GR_int;
  617. X        pVElt->u.iVal = getfixnum(pXElt);
  618. X        break;
  619. X        
  620. X    case FLONUM:
  621. X        pVElt->iType = GR_float;
  622. X        pVElt->u.fVal = (float) getflonum(pXElt);
  623. X        break;
  624. X        
  625. X    case STRING:
  626. X        pVElt->iType = GR_string;
  627. X        pVElt->u.pS = strdup((char *) getstring(pXElt));
  628. X        break;
  629. X        
  630. X    case SYMBOL:
  631. X        pVElt->iType = GR_prim;
  632. X        pVElt->u.pS = strdup(getstring(getpname(pXElt)));
  633. X        break;
  634. X        
  635. X    default:
  636. X        iErr = NATIVE_BADVTYPE;
  637. X        break;
  638. X
  639. X        }
  640. X    }
  641. X
  642. X    pVElt->tLastMod = time;
  643. X
  644. X    return(iErr);
  645. X
  646. X    } /* Native_XEltToNewVElt */
  647. X/****************************************************************************************/
  648. X
  649. X
  650. X
  651. X/****************************************************************************************/
  652. XTVeosErr Native_ListToNewGrouple(pList, hGrouple, time)
  653. X    LVAL    pList;
  654. X    THGrouple    hGrouple;
  655. X    TTimeStamp    time;
  656. X{
  657. X    TVeosErr    iErr;
  658. X    LVAL    pXFinger;
  659. X    int        iElt;
  660. X    TPGrouple    pGrouple;
  661. X    TPElt    pVFinger;
  662. X
  663. X    xlsave1(pXFinger);
  664. X    
  665. X    *hGrouple = nil;
  666. X
  667. X    iErr = Nancy_NewGrouple(&pGrouple);
  668. X    iElt = 0;
  669. X
  670. X
  671. X    /** convert each lisp sub-element **/
  672. X
  673. X    pXFinger = pList;
  674. X    while (!null(pXFinger) && iErr == VEOS_SUCCESS) {
  675. X
  676. X
  677. X    /** make room for another grouple element **/
  678. X    
  679. X    Nancy_NewElementsInGrouple(pGrouple, iElt, 1, GR_unspecified, 0);
  680. X
  681. X
  682. X    /** do actual element conversion **/
  683. X
  684. X    iErr = Native_XEltToNewVElt(car(pXFinger), &pGrouple->pEltList[iElt], time);
  685. X
  686. X
  687. X    /** advance element refs **/
  688. X
  689. X    iElt ++;
  690. X    pXFinger = cdr(pXFinger);
  691. X
  692. X    } /* while */
  693. X
  694. X
  695. X    if (iErr == VEOS_SUCCESS)
  696. X    *hGrouple = pGrouple;
  697. X    else
  698. X    Nancy_DisposeGrouple(pGrouple);
  699. X
  700. X    xlpop();
  701. X
  702. X    return(iErr);
  703. X
  704. X    } /* Native_ListToNewGrouple */
  705. X/****************************************************************************************/
  706. X
  707. X
  708. X
  709. X/****************************************************************************************/
  710. XTVeosErr Native_VectToNewGrouple(pVect, hGrouple, time)
  711. X    LVAL    pVect;
  712. X    THGrouple    hGrouple;
  713. X    TTimeStamp    time;
  714. X{
  715. X    TVeosErr    iErr;
  716. X    int        iElts, iEltIndex;
  717. X    TPGrouple    pGrouple;
  718. X
  719. X
  720. X    *hGrouple = nil;
  721. X
  722. X    iErr = Nancy_NewGrouple(&pGrouple);
  723. X
  724. X
  725. X    iElts = getsz(pVect);
  726. X    if (iElts > 0 && iErr == VEOS_SUCCESS) {
  727. X
  728. X    /** make enough room for all impending elements **/
  729. X
  730. X    iErr = Nancy_NewElementsInGrouple(pGrouple, 0, iElts, GR_unspecified, 0);
  731. X
  732. X
  733. X
  734. X    /** convert each lisp sub-element **/
  735. X
  736. X    iEltIndex = 0;
  737. X    while (iEltIndex < iElts && iErr == VEOS_SUCCESS) {
  738. X
  739. X        iErr = Native_XEltToNewVElt(getelement(pVect, iEltIndex),
  740. X                    &pGrouple->pEltList[iEltIndex], time);
  741. X        iEltIndex ++;
  742. X        }
  743. X    }
  744. X
  745. X    if (iErr == VEOS_SUCCESS)
  746. X    *hGrouple = pGrouple;
  747. X    else
  748. X    Nancy_DisposeGrouple(pGrouple);
  749. X
  750. X
  751. X    return(iErr);
  752. X
  753. X    } /* Native_VectToNewGrouple */
  754. X/****************************************************************************************/
  755. X
  756. X
  757. X/****************************************************************************************
  758. X               Pattern Xlisp <--> Nancy Conversion
  759. X ****************************************************************************************/
  760. X
  761. X
  762. X/****************************************************************************************/
  763. XTVeosErr Native_GetPatternArg(hPattern, iMatchFlag)
  764. X    THGrouple    hPattern;
  765. X    int        iMatchFlag;
  766. X{    
  767. X    LVAL    pXElt;
  768. X    TVeosErr    iErr;
  769. X
  770. X
  771. X    SUBST = FALSE;
  772. X    VOID = FALSE;
  773. X    MOD = (iMatchFlag == NANCY_ReplaceMatch);
  774. X
  775. X
  776. X    /** get lisp pattern list **/
  777. X
  778. X    pXElt = xlgalist();
  779. X
  780. X
  781. X    /** dispatch lisp->veos conversion **/
  782. X
  783. X    iErr = Native_PatListToGrouple(pXElt, hPattern);
  784. X
  785. X#ifndef OPTIMAL
  786. X    if (iErr == VEOS_SUCCESS) {
  787. X    if (iMatchFlag == NANCY_ReplaceMatch) {
  788. X        if (!SUBST && !VOID)
  789. X        iErr = NATIVE_NOREPLACEMARK;
  790. X        }
  791. X    else {
  792. X        if (VOID)
  793. X        iErr = NATIVE_NOVOID;
  794. X        else if (!SUBST)
  795. X        iErr = NATIVE_NOFETCHMARK;
  796. X        }
  797. X    }
  798. X#endif
  799. X
  800. X    return(iErr);
  801. X
  802. X    } /* Native_GetPatternArg */
  803. X/****************************************************************************************/
  804. X
  805. X
  806. X
  807. X/****************************************************************************************/
  808. XTVeosErr Native_PatXEltToVElt(pXElt, pVElt)
  809. X    LVAL     pXElt;
  810. X    TPElt    pVElt;
  811. X{
  812. X    TVeosErr    iErr;
  813. X
  814. X    iErr = VEOS_SUCCESS;
  815. X
  816. X
  817. X    /** NIL is the empty grouple **/
  818. X
  819. X    if (null(pXElt)) {
  820. X    iErr = Nancy_NewGrouple(&pVElt->u.pGr);
  821. X    pVElt->iType = GR_grouple;
  822. X    }
  823. X
  824. X
  825. X    /** case-wise conversion to nancy format **/
  826. X
  827. X    else {
  828. X    switch (ntype(pXElt)) {
  829. X
  830. X    case CONS:
  831. X        /** a list becomes a grouple **/
  832. X        iErr = Native_PatListToGrouple(pXElt, &pVElt->u.pGr);
  833. X        pVElt->iType = GR_grouple;
  834. X        break;
  835. X        
  836. X    case VECTOR:
  837. X        /** a vector becomes a special grouple **/
  838. X        iErr = Native_PatVectToGrouple(pXElt, &pVElt->u.pGr);
  839. X        pVElt->iType = GR_vector;
  840. X        break;
  841. X
  842. X    case FIXNUM:
  843. X        pVElt->iType = GR_int;
  844. X        pVElt->u.iVal = getfixnum(pXElt);
  845. X        break;
  846. X        
  847. X    case FLONUM:
  848. X        pVElt->iType = GR_float;
  849. X        pVElt->u.fVal = (float) getflonum(pXElt);
  850. X        break;
  851. X        
  852. X    case STRING:
  853. X        pVElt->iType = GR_string;
  854. X        pVElt->u.pS = strdup((char *) getstring(pXElt));
  855. X        break;
  856. X        
  857. X    case SYMBOL:
  858. X        iErr = Native_ConvertSymbol(pXElt, pVElt);
  859. X        break;
  860. X        
  861. X    default:
  862. X        iErr = NATIVE_BADVTYPE;
  863. X        break;
  864. X        }
  865. X    }
  866. X
  867. X    return(iErr);
  868. X
  869. X    } /* Native_PatXEltToVElt */
  870. X/****************************************************************************************/
  871. X
  872. X
  873. X
  874. X/****************************************************************************************/
  875. XTVeosErr Native_PatListToGrouple(pList, hGrouple)
  876. X    LVAL    pList;
  877. X    THGrouple    hGrouple;
  878. X{
  879. X    TVeosErr    iErr;
  880. X    LVAL    pXFinger;
  881. X    int        iElt;
  882. X    TPGrouple    pGrouple;
  883. X    TPElt    pVFinger;
  884. X    TPatStatRec    patPB;
  885. X    TElt    eltNew;
  886. X
  887. X    
  888. X    /******************
  889. X     ** setup locals **
  890. X     ******************/
  891. X
  892. X    *hGrouple = nil;
  893. X    iErr = Nancy_NewGrouple(&pGrouple);
  894. X
  895. X    /** by default, a grouple is literally an ordered list of elements.
  896. X     **    in some cases, a pattern grouple can specifiy an order-blind element
  897. X     ** collection.  in other words, a content-dependent-pattern.
  898. X     **/
  899. X    patPB.bOrdered = TRUE;
  900. X
  901. X    /** prepare to check for pattern format inconsistencies **/
  902. X
  903. X    patPB.bExpContent = FALSE;
  904. X    patPB.bExpOrder = FALSE;
  905. X    patPB.bMarkedWithin = FALSE;
  906. X    patPB.bTouchedWithin = FALSE;
  907. X    
  908. X    patPB.bMarkNextElt = FALSE;
  909. X    patPB.bTouchNextElt = FALSE;
  910. X    patPB.bMustEnd = FALSE;
  911. X    patPB.bGetAnother = FALSE;
  912. X
  913. X
  914. X    /***********************************
  915. X     ** convert each lisp sub-element **
  916. X     ***********************************/
  917. X
  918. X    pXFinger = pList;
  919. X    while (!null(pXFinger)) {
  920. X
  921. X    eltNew = NIL_ELT;
  922. X
  923. X    /** do actual element conversion **/
  924. X    
  925. X    iErr = Native_PatXEltToVElt(car(pXFinger), &eltNew);
  926. X    if (iErr != VEOS_SUCCESS)
  927. X        break;
  928. X    
  929. X    iErr = Native_PatVEltClerical(&eltNew, &patPB);
  930. X    if (iErr != VEOS_SUCCESS)
  931. X        break;
  932. X    
  933. X    if (patPB.bGetAnother) {
  934. X        
  935. X        /** this elt was actually a modifier elt for next one.
  936. X         ** prepare for caller forgetting to pass next elt
  937. X         **/
  938. X        iErr = NATIVE_NOTEND;
  939. X        }
  940. X    
  941. X    else {
  942. X        /** place converted nancy element into dest grouple **/
  943. X        
  944. X        Nancy_NewElementsInGrouple(pGrouple, pGrouple->iElts,
  945. X                       1, GR_unspecified, 0);
  946. X        pGrouple->pEltList[pGrouple->iElts - 1] = eltNew;
  947. X        }        
  948. X    
  949. X    
  950. X    /** advance element refs **/
  951. X    
  952. X    pXFinger = cdr(pXFinger);
  953. X    } /* while */
  954. X
  955. X    if (iErr != VEOS_SUCCESS)
  956. X    Nancy_DisposeGrouple(pGrouple);
  957. X
  958. X    else {
  959. X    if (!patPB.bOrdered)
  960. X        SETFLAG(NANCY_ContentMask, pGrouple->iFlags);
  961. X    if (patPB.bMarkedWithin)
  962. X        SETFLAG(NANCY_MarkWithinMask, pGrouple->iFlags);
  963. X    if (patPB.bTouchedWithin)
  964. X        SETFLAG(NANCY_TouchWithinMask, pGrouple->iFlags);
  965. X
  966. X    *hGrouple = pGrouple;
  967. X    }
  968. X
  969. X    return(iErr);
  970. X
  971. X    } /* Native_PatListToGrouple */
  972. X/****************************************************************************************/
  973. X
  974. X
  975. X
  976. X/****************************************************************************************/
  977. XTVeosErr Native_PatVectToGrouple(pVect, hGrouple)
  978. X    LVAL    pVect;
  979. X    THGrouple    hGrouple;
  980. X{
  981. X    TVeosErr    iErr;
  982. X    LVAL    pXFinger;
  983. X    int        iXElts, iXEltIndex;
  984. X    TPGrouple    pGrouple;
  985. X    TPatStatRec    patPB;
  986. X    TElt    eltNew;
  987. X
  988. X    /******************
  989. X     ** setup locals **
  990. X     ******************/
  991. X
  992. X    *hGrouple = nil;
  993. X    iErr = Nancy_NewGrouple(&pGrouple);
  994. X
  995. X    /** by default, a grouple is literally an ordered list of elements.
  996. X     **    in some cases, a pattern grouple can specifiy an order-blind element
  997. X     ** collection.  in other words, a content-dependent-pattern.
  998. X     **/
  999. X    patPB.bOrdered = TRUE;
  1000. X
  1001. X    /** prepare to check for pattern format inconsistencies **/
  1002. X
  1003. X    patPB.bExpContent = FALSE;
  1004. X    patPB.bExpOrder = FALSE;
  1005. X    patPB.bMarkedWithin = FALSE;
  1006. X    patPB.bTouchedWithin = FALSE;
  1007. X    
  1008. X    patPB.bMarkNextElt = FALSE;
  1009. X    patPB.bTouchNextElt = FALSE;
  1010. X    patPB.bMustEnd = FALSE;
  1011. X    patPB.bGetAnother = FALSE;
  1012. X
  1013. X    iXElts = getsz(pVect);
  1014. X    if (iXElts > 0 && iErr == VEOS_SUCCESS) {
  1015. X
  1016. X    /***********************************
  1017. X     ** convert each lisp sub-element **
  1018. X     ***********************************/
  1019. X    
  1020. X    iXEltIndex = 0;
  1021. X    while (iXEltIndex < iXElts) {
  1022. X        
  1023. X
  1024. X        /** cache current vector element **/
  1025. X        
  1026. X        pXFinger = getelement(pVect, iXEltIndex);
  1027. X        eltNew = NIL_ELT;
  1028. X        
  1029. X        /** do actual element conversion **/
  1030. X        
  1031. X        iErr = Native_PatXEltToVElt(pXFinger, &eltNew);
  1032. X        if (iErr != VEOS_SUCCESS)
  1033. X        break;
  1034. X        
  1035. X        iErr = Native_PatVEltClerical(&eltNew, &patPB);
  1036. X        if (iErr != VEOS_SUCCESS)
  1037. X        break;
  1038. X        
  1039. X        if (patPB.bGetAnother) {
  1040. X
  1041. X        /** this elt was actually a modifier elt for next one.
  1042. X         ** prepare for caller forgetting to pass next elt
  1043. X         **/
  1044. X        iErr = NATIVE_NOTEND;
  1045. X        }
  1046. X
  1047. X        else {
  1048. X        /** place converted nancy element into dest grouple **/
  1049. X        
  1050. X        Nancy_NewElementsInGrouple(pGrouple, pGrouple->iElts,
  1051. X                       1, GR_unspecified, 0);
  1052. X        pGrouple->pEltList[pGrouple->iElts - 1] = eltNew;
  1053. X        }        
  1054. X
  1055. X
  1056. X        /** advance element refs **/
  1057. X        
  1058. X        iXEltIndex ++;
  1059. X
  1060. X        } /* while */
  1061. X    }
  1062. X
  1063. X    if (iErr != VEOS_SUCCESS)
  1064. X    Nancy_DisposeGrouple(pGrouple);
  1065. X
  1066. X    else {
  1067. X    if (!patPB.bOrdered)
  1068. X        SETFLAG(NANCY_ContentMask, pGrouple->iFlags);
  1069. X    if (patPB.bMarkedWithin)
  1070. X        SETFLAG(NANCY_MarkWithinMask, pGrouple->iFlags);
  1071. X    if (patPB.bTouchedWithin)
  1072. X        SETFLAG(NANCY_TouchWithinMask, pGrouple->iFlags);
  1073. X
  1074. X    *hGrouple = pGrouple;
  1075. X    }
  1076. X
  1077. X    return(iErr);
  1078. X
  1079. X    } /* Native_PatVectToGrouple */
  1080. X/****************************************************************************************/
  1081. X
  1082. X
  1083. X
  1084. X/****************************************************************************************/
  1085. XTVeosErr Native_PatVEltClerical(pVElt, pStats)
  1086. X    TPElt        pVElt;
  1087. X    TPPatStatRec    pStats;
  1088. X{
  1089. X    TVeosErr        iErr = VEOS_SUCCESS;
  1090. X
  1091. X#ifndef OPTIMAL
  1092. X    if (pStats->bMustEnd)
  1093. X    iErr = NATIVE_NOTEND;
  1094. X
  1095. X    else {
  1096. X    /** catch possible undefined expressions **/
  1097. X    
  1098. X    switch (pVElt->iType) {
  1099. X        
  1100. X    case GR_these:
  1101. X        if (pStats->bExpContent)
  1102. X        iErr = NATIVE_CANTMIX;
  1103. X        break;
  1104. X        
  1105. X    case GR_theseall:
  1106. X        if (pStats->bExpContent)
  1107. X        iErr = NATIVE_CANTMIX;
  1108. X        break;
  1109. X        
  1110. X    case GR_some:
  1111. X        iErr = NATIVE_NOSTARN;
  1112. X        break;
  1113. X        
  1114. X    case GR_any:
  1115. X        if (pStats->bExpOrder)
  1116. X        iErr = NATIVE_CANTMIX;
  1117. X        break;
  1118. X        
  1119. X    case GR_here:
  1120. X        if (SUBST || VOID) 
  1121. X        iErr = NATIVE_TOOMANYMARKS;
  1122. X        else if (pStats->bGetAnother)
  1123. X        iErr = NATIVE_MODVOID;
  1124. X        break;
  1125. X        
  1126. X    case GR_mark:
  1127. X        if (SUBST || VOID) 
  1128. X        iErr = NATIVE_TOOMANYMARKS;
  1129. X        else if (pStats->bGetAnother)
  1130. X        iErr = NATIVE_THISWHAT;
  1131. X        break;
  1132. X
  1133. X    case GR_touch:
  1134. X        if (!MOD)
  1135. X        iErr = NATIVE_NOTOUCH;
  1136. X        else if (pStats->bGetAnother)
  1137. X        iErr = NATIVE_THISWHAT;
  1138. X        break;
  1139. X
  1140. X    default:
  1141. X        break;
  1142. X        } /* switch */
  1143. X    }
  1144. X#endif    
  1145. X
  1146. X    if (iErr == VEOS_SUCCESS) {
  1147. X
  1148. X    /** mark the element for nancy matcher **/
  1149. X    
  1150. X    if (pStats->bMarkNextElt) {
  1151. X        SETFLAG(NANCY_EltMarkMask, pVElt->iFlags);
  1152. X        pStats->bMarkNextElt = FALSE;
  1153. X        pStats->bGetAnother = FALSE;
  1154. X        }
  1155. X
  1156. X    if (pStats->bTouchNextElt) {
  1157. X        SETFLAG(NANCY_EltTouchMask, pVElt->iFlags);
  1158. X        pStats->bTouchNextElt = FALSE;
  1159. X        pStats->bGetAnother = FALSE;
  1160. X        }
  1161. X
  1162. X
  1163. X    switch (pVElt->iType) {
  1164. X        
  1165. X    case GR_these:
  1166. X        pStats->bExpOrder = TRUE;
  1167. X        break;
  1168. X        
  1169. X    case GR_any:
  1170. X        pStats->bOrdered = FALSE;
  1171. X        pStats->bExpContent = TRUE;
  1172. X        pStats->bMustEnd = TRUE;
  1173. X        break;
  1174. X        
  1175. X    case GR_theseall:
  1176. X        pStats->bExpOrder = TRUE;
  1177. X        pStats->bMustEnd = TRUE;
  1178. X        break;
  1179. X        
  1180. X    case GR_here:
  1181. X        VOID = TRUE;
  1182. X        SETFLAG(NANCY_EltMarkMask, pVElt->iFlags);
  1183. X        pStats->bMarkedWithin = TRUE;
  1184. X        break;
  1185. X        
  1186. X    case GR_mark:
  1187. X        SUBST = TRUE;
  1188. X        pStats->bMarkedWithin = TRUE;
  1189. X        pStats->bMarkNextElt = TRUE;        
  1190. X        pStats->bGetAnother = TRUE;        
  1191. X        break;
  1192. X        
  1193. X    case GR_touch:
  1194. X        pStats->bTouchedWithin = TRUE;
  1195. X        pStats->bTouchNextElt = TRUE;        
  1196. X        pStats->bGetAnother = TRUE;        
  1197. X        break;
  1198. X        
  1199. X    default:
  1200. X        break;
  1201. X        } /* switch */
  1202. X    }
  1203. X
  1204. X    return(iErr);
  1205. X
  1206. X    } /* Native_PatVEltClerical */
  1207. X/****************************************************************************************/
  1208. X
  1209. X
  1210. X
  1211. X/****************************************************************************************/
  1212. XTVeosErr Native_ConvertSymbol(pXElt, pVElt)
  1213. X    LVAL    pXElt;
  1214. X    TPElt    pVElt;
  1215. X{
  1216. X    TVeosErr    iErr = VEOS_SUCCESS;
  1217. X    char    *sSrc;
  1218. X    boolean    bParsed = FALSE;
  1219. X
  1220. X
  1221. X    sSrc = (char *) getstring(getpname(pXElt));
  1222. X
  1223. X    switch(sSrc[0]) {
  1224. X
  1225. X    
  1226. X    case '^':     /* '^' marks the void for insertion */
  1227. X    if (sSrc[1] == '\0') {
  1228. X        pVElt->iType = GR_here;
  1229. X        bParsed = TRUE;
  1230. X        }
  1231. X    break;
  1232. X
  1233. X    case '>':   /* '>' is a mark for the next element */
  1234. X    if (sSrc[1] == '\0') {
  1235. X        pVElt->iType = GR_mark;
  1236. X        bParsed = TRUE;
  1237. X        }
  1238. X    break;
  1239. X
  1240. X    case '~':   /* '~' touches the next element */
  1241. X    if (sSrc[1] == '\0') {
  1242. X        pVElt->iType = GR_touch;
  1243. X        bParsed = TRUE;
  1244. X        }
  1245. X    break;
  1246. X
  1247. X    case '@':     /* '@' is wildcard for ordered elements **/
  1248. X    
  1249. X    /** special form (@) means exactly one element **/
  1250. X    if (sSrc[1] == '\0') {
  1251. X        pVElt->iType = GR_these;
  1252. X        pVElt->u.iVal = 1;
  1253. X        bParsed = TRUE;
  1254. X        }
  1255. X    
  1256. X    /** special form (@n) means exactly n elts **/
  1257. X    else if (IsIntStr(&sSrc[1]) == VEOS_SUCCESS) {
  1258. X        if ((pVElt->u.iVal = atoi(&sSrc[1])) < 1)
  1259. X        iErr = NATIVE_CRAZYWILD;
  1260. X        else
  1261. X        pVElt->iType = GR_these;
  1262. X        bParsed = TRUE;
  1263. X        }
  1264. X    
  1265. X    /** special form (@@) means zero or more elts **/
  1266. X    else if (sSrc[1] == '@' && sSrc[2] == '\0') {
  1267. X        pVElt->iType = GR_theseall;
  1268. X        bParsed = TRUE;
  1269. X        }
  1270. X    break;
  1271. X
  1272. X
  1273. X    case '*':   /* '*' is wildcard for unordered elements */
  1274. X    
  1275. X    /** special form (*) means exatly one element **/
  1276. X    if (sSrc[1] == '\0') {
  1277. X        pVElt->iType = GR_some;
  1278. X        pVElt->u.iVal = 1;
  1279. X        bParsed = TRUE;
  1280. X        }
  1281. X    
  1282. X    /** special form (*n) means exactly n elts **/
  1283. X    else if (IsIntStr(&sSrc[1]) == VEOS_SUCCESS) {
  1284. X        if ((pVElt->u.iVal = atoi(&sSrc[1])) < 1)
  1285. X        iErr = NATIVE_CRAZYWILD;
  1286. X        else
  1287. X        pVElt->iType = GR_some;
  1288. X        bParsed = TRUE;
  1289. X        }
  1290. X    
  1291. X    /** special form (**) means zero or more elts **/
  1292. X    else if (sSrc[1] == '*' && sSrc[2] == '\0') {
  1293. X        pVElt->iType = GR_any;
  1294. X        bParsed = TRUE;
  1295. X        }
  1296. X    break;
  1297. X
  1298. X    } /* switch */
  1299. X
  1300. X
  1301. X    /** save symbol's name as veos prim type **/
  1302. X    
  1303. X    if (!bParsed && iErr == VEOS_SUCCESS) {
  1304. X    pVElt->iType = GR_prim;
  1305. X    pVElt->u.pS = strdup(sSrc);
  1306. X    }
  1307. X    
  1308. X
  1309. X    return(iErr);
  1310. X
  1311. X    } /* Native_ConvertSymbol */
  1312. X/****************************************************************************************/
  1313. X
  1314. X
  1315. X
  1316. X/****************************************************************************************
  1317. X              Xlisp <--> Linearized Data Conversion
  1318. X ****************************************************************************************/
  1319. X
  1320. X
  1321. X/****************************************************************************************/
  1322. XTVeosErr Native_XEltToMsgRec(pXData, pMsgRec)
  1323. X    LVAL         pXData;
  1324. X    TPMsgRec        pMsgRec;
  1325. X{
  1326. X    TVeosErr        iErr;
  1327. X
  1328. X    pMsgRec->iLen = 0;
  1329. X    pMsgRec->sMessage = TALK_BUFFER;
  1330. X
  1331. X
  1332. X    /** perform data conversion to flat network-friendly form **/
  1333. X
  1334. X    iErr = Native_XEltToMessage(pXData, pMsgRec->sMessage, &pMsgRec->iLen);
  1335. X
  1336. X    if (iErr != VEOS_SUCCESS)
  1337. X    Native_TrapErr(iErr, pXData);
  1338. X
  1339. X
  1340. X    return(iErr);
  1341. X
  1342. X    } /* Native_XEltToMsgRec */
  1343. X/****************************************************************************************/
  1344. X
  1345. X
  1346. X
  1347. X/****************************************************************************************/
  1348. XTVeosErr Native_XEltToMessage(pXElt, pBuffer, pLen)
  1349. X    LVAL         pXElt;
  1350. X    char        *pBuffer;
  1351. X    int            *pLen;
  1352. X{
  1353. X    TVeosErr        iErr;
  1354. X    int            iLen;
  1355. X    TF2L        fTrans;
  1356. X
  1357. X    iErr = VEOS_SUCCESS;
  1358. X
  1359. X    /** message element is: element type, then data (except for NIL)
  1360. X     ** assume pBuffer is aligned 
  1361. X     **/
  1362. X
  1363. X    if (null(pXElt)) {
  1364. X
  1365. X    /** nil element is empty grouple **/
  1366. X    *(int *) pBuffer = htonl(GR_grouple);    
  1367. X    pBuffer += 4;
  1368. X
  1369. X    /** empty grouple has zero elements **/
  1370. X    *(int *) pBuffer = htonl(0);    
  1371. X
  1372. X    iLen = 8;
  1373. X    }
  1374. X    else {
  1375. X
  1376. X    switch (ntype(pXElt)) {
  1377. X        
  1378. X    case CONS:
  1379. X        *(int *) pBuffer = htonl(GR_grouple);    
  1380. X        pBuffer += 4;
  1381. X        iLen = 4;
  1382. X        iErr = Native_ListToMessage(pXElt, pBuffer, &iLen);
  1383. X        break;
  1384. X
  1385. X    case VECTOR:
  1386. X        *(int *) pBuffer = htonl(GR_vector);    
  1387. X        pBuffer += 4;
  1388. X        iLen = 4;
  1389. X        iErr = Native_VectToMessage(pXElt, pBuffer, &iLen);
  1390. X        break;
  1391. X
  1392. X    case FIXNUM:
  1393. X        *(int *) pBuffer = htonl(GR_int);    
  1394. X        pBuffer += 4;
  1395. X        *(long *) pBuffer = htonl(getfixnum(pXElt));
  1396. X        iLen = 8;
  1397. X        break;
  1398. X        
  1399. X    case FLONUM:
  1400. X        *(int *) pBuffer = htonl(GR_float);    
  1401. X        pBuffer += 4;
  1402. X        fTrans.u.f = getflonum(pXElt);
  1403. X        *(long *) pBuffer = htonl(fTrans.u.l);
  1404. X        iLen = 8;
  1405. X        break;
  1406. X        
  1407. X    case STRING:
  1408. X        *(int *) pBuffer = htonl(GR_string);    
  1409. X        pBuffer += 4;
  1410. X        strcpy(pBuffer, getstring(pXElt));
  1411. X        iLen = 4 + MEMSIZE(strlen(getstring(pXElt)) + 1);
  1412. X        break;
  1413. X        
  1414. X    case SYMBOL:
  1415. X        *(int *) pBuffer = htonl(GR_prim);    
  1416. X        pBuffer += 4;
  1417. X        strcpy(pBuffer, getstring(getpname(pXElt)));
  1418. X        iLen = 4 + MEMSIZE(strlen(getstring(getpname(pXElt))) + 1);
  1419. X        break;
  1420. X        
  1421. X    default:
  1422. X        iErr = NATIVE_BADVTYPE;
  1423. X        iLen = 0;
  1424. X        break;
  1425. X
  1426. X        } /* switch */
  1427. X    }
  1428. X
  1429. X    *pLen += iLen;
  1430. X
  1431. X    return(iErr);
  1432. X
  1433. X    } /* Native_XEltToMessage */
  1434. X/****************************************************************************************/
  1435. X
  1436. X
  1437. X
  1438. X/****************************************************************************************/
  1439. XTVeosErr Native_ListToMessage(pList, pBuffer, pLen)
  1440. X    LVAL    pList;
  1441. X    char    *pBuffer;
  1442. X    int        *pLen;
  1443. X{
  1444. X    TVeosErr    iErr = VEOS_SUCCESS;
  1445. X    LVAL    pXFinger;
  1446. X    int        iLen, iElts = 0;
  1447. X    char    *pListHead;
  1448. X
  1449. X
  1450. X    /** first code of protocol is number of elements, write later **/
  1451. X    
  1452. X    pListHead = pBuffer;
  1453. X    pBuffer = pListHead + 4;
  1454. X    *pLen += 4;
  1455. X
  1456. X    
  1457. X    /** convert each lisp sub-element **/
  1458. X
  1459. X    pXFinger = pList;
  1460. X    while (!null(pXFinger)) {
  1461. X
  1462. X    /** invoke recursive translation **/
  1463. X
  1464. X    iLen = 0;
  1465. X    iErr = Native_XEltToMessage(car(pXFinger), pBuffer, &iLen);
  1466. X
  1467. X    if (iErr != VEOS_SUCCESS) 
  1468. X        break;
  1469. X
  1470. X    else {
  1471. X        iElts ++;
  1472. X
  1473. X        pBuffer += iLen;
  1474. X        *pLen += iLen;
  1475. X        }
  1476. X
  1477. X    /** advance element ref **/
  1478. X    
  1479. X    pXFinger = cdr(pXFinger);
  1480. X    
  1481. X    } /* while */
  1482. X
  1483. X
  1484. X    /** write number of elements **/
  1485. X
  1486. X    *(int *) pListHead = htonl(iElts);
  1487. X
  1488. X    return(iErr);
  1489. X
  1490. X    } /* Native_ListToMessage */
  1491. X/****************************************************************************************/
  1492. X
  1493. X
  1494. X
  1495. X
  1496. X/****************************************************************************************/
  1497. XTVeosErr Native_VectToMessage(pVect, pBuffer, pLen)
  1498. X    LVAL    pVect;
  1499. X    char    *pBuffer;
  1500. X    int        *pLen;
  1501. X{
  1502. X    TVeosErr    iErr = VEOS_SUCCESS;
  1503. X    LVAL    pXFinger;
  1504. X    int        iLen, iEltIndex, iElts;
  1505. X
  1506. X    iElts = getsz(pVect);
  1507. X
  1508. X    /** first code of protocol is number of elements **/
  1509. X    *(int *) pBuffer = htonl(iElts);
  1510. X
  1511. X    pBuffer += 4;
  1512. X    *pLen += 4;
  1513. X
  1514. X    
  1515. X    /** convert each lisp sub-element **/
  1516. X
  1517. X    iEltIndex = 0;
  1518. X    while(iEltIndex < iElts) {
  1519. X
  1520. X
  1521. X    /** invoke recursive translation **/
  1522. X
  1523. X    iLen = 0;
  1524. X    iErr = Native_XEltToMessage(getelement(pVect, iEltIndex), pBuffer, &iLen);
  1525. X
  1526. X    if (iErr != VEOS_SUCCESS) 
  1527. X        break;
  1528. X
  1529. X    else {
  1530. X        pBuffer += iLen;
  1531. X        *pLen += iLen;
  1532. X        }
  1533. X
  1534. X
  1535. X    /** advance element ref **/
  1536. X
  1537. X    iEltIndex ++;
  1538. X
  1539. X    } /* while */
  1540. X
  1541. X    
  1542. X    return(iErr);
  1543. X
  1544. X    } /* Native_VectToMessage */
  1545. X/****************************************************************************************/
  1546. X
  1547. X
  1548. X
  1549. X
  1550. X/****************************************************************************************/
  1551. XTVeosErr Native_MessageToXElt(pBuffer, hXElt, pLen)
  1552. X    char        *pBuffer;
  1553. X    LVAL         *hXElt;
  1554. X    int            *pLen;
  1555. X{
  1556. X    TVeosErr        iErr = VEOS_SUCCESS;
  1557. X    int            iLen, iType;
  1558. X    TF2L        fTrans;
  1559. X
  1560. X    *hXElt = NIL;
  1561. X
  1562. X    iType = ntohl(*(int *) pBuffer);    /** assume pBuffer is aligned **/
  1563. X
  1564. X    pBuffer += 4;
  1565. X    *pLen += 4;
  1566. X
  1567. X    switch (iType) {
  1568. X        
  1569. X    case GR_grouple:
  1570. X    iLen = 0;
  1571. X    iErr = Native_MessageToList(pBuffer, hXElt, &iLen);
  1572. X    break;
  1573. X
  1574. X    case GR_vector:
  1575. X    iLen = 0;
  1576. X    iErr = Native_MessageToVect(pBuffer, hXElt, &iLen);
  1577. X    break;
  1578. X
  1579. X    case GR_int:
  1580. X    *hXElt = cvfixnum((int) ntohl(*(long *) pBuffer));
  1581. X    iLen = 4;
  1582. X    break;
  1583. X             
  1584. X    case GR_float:
  1585. X    fTrans.u.l = ntohl(*(long *) pBuffer);
  1586. X    *hXElt = cvflonum(fTrans.u.f);
  1587. X    iLen = 4;
  1588. X    break;
  1589. X
  1590. X    case GR_string:
  1591. X    *hXElt = cvstring(pBuffer);
  1592. X    iLen = MEMSIZE(strlen(pBuffer) + 1);  
  1593. X    break;
  1594. X
  1595. X    case GR_prim:
  1596. X    *hXElt = xlenter(pBuffer);
  1597. X    iLen = MEMSIZE(strlen(pBuffer) + 1);  
  1598. X    break;
  1599. X
  1600. X    case GR_unspecified:
  1601. X    default:
  1602. X    iLen = 0;
  1603. X    break;
  1604. X        
  1605. X    } /* switch */
  1606. X
  1607. X    *pLen += iLen;
  1608. X    
  1609. X    return(iErr);
  1610. X
  1611. X    } /* Native_MessageToXElt */
  1612. X/****************************************************************************************/
  1613. X
  1614. X
  1615. X
  1616. X/****************************************************************************************/
  1617. XTVeosErr Native_MessageToList(pBuffer, hList, pLen)
  1618. X    char    *pBuffer;
  1619. X    LVAL    *hList;
  1620. X    int        *pLen;
  1621. X{
  1622. X    TVeosErr    iErr = VEOS_SUCCESS;
  1623. X    LVAL    pXFinger;
  1624. X    int        iLen, iElts, iEltIndex;
  1625. X    char    *pListHead;
  1626. X    LVAL    pList, pXElt;
  1627. X
  1628. X    xlstkcheck(2);
  1629. X    xlsave(pList);
  1630. X    xlsave(pXElt);
  1631. X
  1632. X    /** extract # of elements from first part of grouple data **/
  1633. X
  1634. X    iElts = ntohl(*(int *) pBuffer);
  1635. X
  1636. X    pBuffer += 4;
  1637. X    *pLen += 4;
  1638. X
  1639. X
  1640. X    /** convert each element one at a time, 'talk msg format' -> list' **/
  1641. X
  1642. X    iEltIndex = 0;
  1643. X    while (iEltIndex < iElts) {
  1644. X
  1645. X    iLen = 0;
  1646. X
  1647. X    /** extract elt data, allocate specific elt mem, stuff it with data. **/
  1648. X
  1649. X    iErr = Native_MessageToXElt(pBuffer, &pXElt, &iLen);
  1650. X
  1651. X    if (iErr != VEOS_SUCCESS)
  1652. X        break;
  1653. X
  1654. X    else {
  1655. X        pBuffer += iLen;
  1656. X        *pLen += iLen;
  1657. X
  1658. X        pList = cons(pXElt, pList);
  1659. X        }
  1660. X
  1661. X    iEltIndex ++;
  1662. X    }
  1663. X
  1664. X    if (iErr == VEOS_SUCCESS) {
  1665. X
  1666. X    *hList = ReverseList(pList);
  1667. X    }
  1668. X
  1669. X    xlpopn(2);
  1670. X
  1671. X    return(iErr);
  1672. X
  1673. X    } /* Native_MessageToList */
  1674. X/****************************************************************************************/
  1675. X
  1676. X
  1677. X
  1678. X
  1679. X/****************************************************************************************/
  1680. XTVeosErr Native_MessageToVect(pBuffer, hVect, pLen)
  1681. X    char    *pBuffer;
  1682. X    LVAL    *hVect;
  1683. X    int        *pLen;
  1684. X{
  1685. X    TVeosErr    iErr = VEOS_SUCCESS;
  1686. X    int        iLen, iElts, iEltIndex;
  1687. X    LVAL    pVect, pXElt;
  1688. X
  1689. X    xlstkcheck(2);
  1690. X    xlsave(pVect);
  1691. X    xlsave(pXElt);
  1692. X
  1693. X    /** extract # of elements from first part of grouple data **/
  1694. X
  1695. X    iElts = ntohl(*(int *) pBuffer);
  1696. X
  1697. X    pBuffer += 4;
  1698. X    *pLen += 4;
  1699. X
  1700. X
  1701. X    /** create new lisp vector as container **/
  1702. X
  1703. X    pVect = newvector(iElts);
  1704. X
  1705. X
  1706. X    /** convert each element one at a time **/
  1707. X
  1708. X    iEltIndex = 0;
  1709. X    while (iEltIndex < iElts) {
  1710. X
  1711. X    iLen = 0;
  1712. X
  1713. X    /** extract elt data, allocate specific elt mem, stuff it with data. **/
  1714. X
  1715. X    iErr = Native_MessageToXElt(pBuffer, &pXElt, &iLen);
  1716. X    if (iErr != VEOS_SUCCESS) 
  1717. X        break;
  1718. X
  1719. X    else {
  1720. X        pBuffer += iLen;
  1721. X        *pLen += iLen;
  1722. X
  1723. X        setelement(pVect, iEltIndex, pXElt);
  1724. X        }
  1725. X
  1726. X    iEltIndex ++;
  1727. X    }
  1728. X
  1729. X
  1730. X    if (iErr == VEOS_SUCCESS)
  1731. X    *hVect = pVect;
  1732. X
  1733. X    xlpopn(2);
  1734. X
  1735. X    return(iErr);
  1736. X
  1737. X    } /* Native_MessageToVect */
  1738. X/****************************************************************************************/
  1739. X
  1740. X
  1741. X
  1742. X/****************************************************************************************/
  1743. XTVeosErr Native_TrapErr(iErr, pXElt)
  1744. X    TVeosErr    iErr;
  1745. X    LVAL    pXElt;
  1746. X{
  1747. X    str63    sErr;
  1748. X
  1749. X    switch(iErr) {
  1750. X
  1751. X    case NATIVE_BADTYPE:
  1752. X    xlbadtype(pXElt);
  1753. X    break;
  1754. X    case NATIVE_NOKERNEL:
  1755. X    xlfail("veos kernel not initialized, use (vinit <port-num>)");
  1756. X    break;
  1757. X    case NATIVE_BADFREQ:
  1758. X    xlerror("'!' expected", pXElt);
  1759. X    break;
  1760. X    case NATIVE_2KERNELS:
  1761. X    xlfail("veos kernel already initialized");
  1762. X    break;
  1763. X    case NATIVE_BADVTYPE:
  1764. X    xlerror("veos does not support that data type", pXElt == nil ? s_unbound : pXElt);
  1765. X    break;
  1766. X    case NATIVE_BADXTYPE:
  1767. X    xlerror("xlisp does not support that data type from veos",
  1768. X        pXElt == nil ? s_unbound : pXElt);
  1769. X    break;
  1770. X    case NATIVE_EMPTYELT:
  1771. X    xlerror("empty data element from veos, probably a memory error",
  1772. X        pXElt == nil ? s_unbound : pXElt);
  1773. X    break;
  1774. X    case NATIVE_NODATA:
  1775. X    xlerror("no veos data to match... only the void remains", s_unbound);
  1776. X    break;
  1777. X    case NATIVE_THISWHAT:
  1778. X    xlerror("pattern element modifier ('>' or '~') must be followed by a matchable element", pXElt == nil ? s_unbound : pXElt);
  1779. X    break;
  1780. X    case NATIVE_TOOMANYMARKS:
  1781. X    xlerror("patterns must contain exactly one '>' or '^'",
  1782. X        pXElt == nil ? s_unbound : pXElt);
  1783. X    break;
  1784. X    case NATIVE_CANTMIX:
  1785. X    xlerror("can't mix '@' and '*'", pXElt == nil ? s_unbound : pXElt);
  1786. X    break;
  1787. X    case NATIVE_NOTEND:
  1788. X    xlerror("indefinite wildcards (eg '@@' or '**') can only appear at end of grouple in pattern",
  1789. X        pXElt == nil ? s_unbound : pXElt);
  1790. X    break;
  1791. X    case NATIVE_NOREPLACEMARK:
  1792. X    xlerror("pattern must contain '>' or '^'", pXElt == nil ? s_unbound : pXElt);
  1793. X    break;
  1794. X    case NATIVE_NOFETCHMARK:
  1795. X    xlerror("pattern must contain '>'", pXElt == nil ? s_unbound : pXElt);
  1796. X    break;
  1797. X    case NATIVE_NOVOID:
  1798. X    xlerror("cannot get or copy from the void ('^')",  
  1799. X        pXElt == nil ? s_unbound : pXElt);
  1800. X    break;
  1801. X    case NATIVE_BADPATSYMBOL:
  1802. X    xlerror("symbol not recognized", pXElt == nil ? s_unbound : pXElt);
  1803. X    break;
  1804. X    case NATIVE_CRAZYWILD:
  1805. X    xlerror("nonsensical number of wildcard elements",
  1806. X        pXElt == nil ? s_unbound : pXElt);
  1807. X    break;
  1808. X    case NATIVE_MATCHFAIL:
  1809. X    xlerror("match and/or replace did not succeed",
  1810. X        pXElt == nil ? s_unbound : pXElt);
  1811. X    break;
  1812. X    case NATIVE_NOSTARN:
  1813. X    xlerror("the '*n' feature is not supported",
  1814. X        pXElt == nil ? s_unbound : pXElt);
  1815. X    break;
  1816. X    case NATIVE_BADVOID:
  1817. X    xlerror("ambiguous void marker (can't use '^' in pattern grouple containing '*')",
  1818. X        pXElt == nil ? s_unbound : pXElt);
  1819. X    break;
  1820. X    case NATIVE_NOHOST:
  1821. X    xlerror("host not recognized", pXElt == nil ? s_unbound : pXElt);
  1822. X    break;
  1823. X    case NATIVE_NOTOUCH:
  1824. X    xlerror("can't touch (eg. '~') elements during nondestructive grouplespace access", pXElt == nil ? s_unbound : pXElt);
  1825. X    break;
  1826. X    case NATIVE_MODVOID:
  1827. X    xlerror("can't use element modifiers ('>' or '~') with the void ('^')", pXElt == nil ? s_unbound : pXElt);
  1828. X    break;
  1829. X    case VEOS_SUCCESS:
  1830. X    break;
  1831. X    default:
  1832. X    sprintf(sErr, "unexpected error %d", iErr);
  1833. X    xlerror(sErr, pXElt == nil ? s_unbound : pXElt);
  1834. X    break;
  1835. X    }
  1836. X
  1837. X    return(VEOS_SUCCESS);
  1838. X
  1839. X    } /* Native_TrapErr */
  1840. X/****************************************************************************************/
  1841. X
  1842. X
  1843. X
  1844. X/****************************************************************************************/
  1845. Xboolean    IsUidElt(pXElt)
  1846. X    LVAL    pXElt;
  1847. X{
  1848. X    return(vectorp(pXElt) &&
  1849. X       getsz(pXElt) == 2 &&
  1850. X       stringp(getelement(pXElt, 0)) &&
  1851. X       fixp(getelement(pXElt, 1)));
  1852. X
  1853. X    } /* IsUidElt */
  1854. X/****************************************************************************************/
  1855. X
  1856. X
  1857. X/****************************************************************************************/
  1858. XTVeosErr XVect2Uid(pXElt, pUid)
  1859. X    LVAL    pXElt;
  1860. X    TPUid    pUid;
  1861. X{
  1862. X    TVeosErr    iErr;
  1863. X
  1864. X    /** assume sanity is checked **/
  1865. X
  1866. X    iErr = Sock_ResolveHost(getstring(getelement(pXElt, 0)), &pUid->lHost);
  1867. X    if (iErr == VEOS_SUCCESS)
  1868. X    pUid->iPort = getfixnum(getelement(pXElt, 1));
  1869. X    else
  1870. X    iErr = NATIVE_NOHOST;
  1871. X
  1872. X    return(iErr);
  1873. X
  1874. X    } /* XVect2Uid */
  1875. X/****************************************************************************************/
  1876. X
  1877. X
  1878. X/****************************************************************************************/
  1879. XTVeosErr Uid2XVect(pUid, hXElt)
  1880. X    TPUid    pUid;
  1881. X    LVAL    *hXElt;
  1882. X{
  1883. X    str255    sTemp;
  1884. X
  1885. X    /** assume sanity is checked **/
  1886. X
  1887. X    if (Sock_IP2StrHost(pUid->lHost, sTemp) == VEOS_SUCCESS ||
  1888. X    Sock_IP2StrAddr(pUid->lHost, sTemp) == VEOS_SUCCESS) {
  1889. X
  1890. X    /** assume caller locked *hXElt **/
  1891. X
  1892. X    *hXElt = newvector(2);
  1893. X    setelement(*hXElt, 0, cvstring(sTemp));
  1894. X    setelement(*hXElt, 1, cvfixnum(pUid->iPort));
  1895. X    }
  1896. X
  1897. X    return(VEOS_SUCCESS);
  1898. X
  1899. X    } /* Uid2XVect */
  1900. X/****************************************************************************************/
  1901. X
  1902. X
  1903. X
  1904. X/****************************************************************************************/
  1905. XTVeosErr Native_XVectsToUids(pList, hDests)
  1906. X    LVAL    pList;
  1907. X    THUidNode    hDests;
  1908. X{
  1909. X    TVeosErr    iErr = VEOS_SUCCESS;
  1910. X    TPUidNode    pDests, pNode;
  1911. X    LVAL    pXFinger;
  1912. X
  1913. X    /** convert lisp 'uid' vectors to nancy uids **/
  1914. X
  1915. X    pDests = nil;
  1916. X    pXFinger = pList;
  1917. X    while (!null(pXFinger)) {
  1918. X
  1919. X#ifndef OPTIMAL    
  1920. X    if (!IsUidElt(car(pXFinger))) {
  1921. X        iErr = NATIVE_BADTYPE;
  1922. X        break;
  1923. X        }
  1924. X#endif
  1925. X    iErr = Shell_NewBlock(sizeof(TUidNode), &pNode, "uid-node");
  1926. X
  1927. X    if (iErr != VEOS_SUCCESS)
  1928. X        break;
  1929. X
  1930. X    else{
  1931. X        /** add new node to list **/
  1932. X        
  1933. X        pNode->pNext = pDests;
  1934. X        pDests = pNode;
  1935. X        
  1936. X        
  1937. X        /** convert addr to internal format **/
  1938. X        
  1939. X        iErr = XVect2Uid(car(pXFinger), &pNode->addr);
  1940. X        }
  1941. X
  1942. X    pXFinger = cdr(pXFinger);
  1943. X
  1944. X    } /* while */
  1945. X
  1946. X    if (iErr == VEOS_SUCCESS)
  1947. X    *hDests = pDests;
  1948. X    else
  1949. X    Native_DisposeUids(pDests);
  1950. X
  1951. X    return(iErr);
  1952. X
  1953. X    } /* Native_XVectsToUids */
  1954. X/****************************************************************************************/
  1955. X
  1956. X
  1957. X
  1958. X/****************************************************************************************/
  1959. XTVeosErr Native_DisposeUids(pDests)
  1960. X    TPUidNode    pDests;
  1961. X{
  1962. X    TPUidNode    pSave;
  1963. X
  1964. X    while (pDests) {
  1965. X
  1966. X    pSave = pDests->pNext;
  1967. X    Shell_ReturnBlock(pDests, sizeof(TUidNode), "uid-node");
  1968. X    pDests = pSave;
  1969. X    }
  1970. X
  1971. X    return(VEOS_SUCCESS);
  1972. X
  1973. X    } /* Native_DisposeUids */
  1974. X/****************************************************************************************/
  1975. X
  1976. X
  1977. X/****************************************************************************************/
  1978. XTVeosErr IsIntStr(sSrc)
  1979. X    char         *sSrc;
  1980. X{
  1981. X    TVeosErr    iErr;
  1982. X
  1983. X    iErr = VEOS_FAILURE;
  1984. X    if (sSrc) {
  1985. X
  1986. X    for (iErr = VEOS_SUCCESS;
  1987. X         sSrc[0] != '\0' && iErr == VEOS_SUCCESS;
  1988. X         sSrc ++)
  1989. X
  1990. X        if (!isdigit(sSrc[0]))
  1991. X        iErr = VEOS_FAILURE;
  1992. X    }
  1993. X
  1994. X    return(iErr);
  1995. X
  1996. X    } /* IsIntStr */
  1997. X/****************************************************************************************/
  1998. X
  1999. X
  2000. END_OF_FILE
  2001. if test 43094 -ne `wc -c <'kernel_private/src/shell/xv_glutils.c'`; then
  2002.     echo shar: \"'kernel_private/src/shell/xv_glutils.c'\" unpacked with wrong size!
  2003. fi
  2004. # end of 'kernel_private/src/shell/xv_glutils.c'
  2005. fi
  2006. echo shar: End of archive 15 \(of 16\).
  2007. cp /dev/null ark15isdone
  2008. MISSING=""
  2009. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  2010.     if test ! -f ark${I}isdone ; then
  2011.     MISSING="${MISSING} ${I}"
  2012.     fi
  2013. done
  2014. if test "${MISSING}" = "" ; then
  2015.     echo You have unpacked all 16 archives.
  2016.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2017. else
  2018.     echo You still need to unpack the following archives:
  2019.     echo "        " ${MISSING}
  2020. fi
  2021. ##  End of shell archive.
  2022. exit 0
  2023.