home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / programm / utility / gawk21.lzh / awk3.c < prev   
Encoding:
Text File  |  1990-09-27  |  23.0 KB  |  698 lines

  1. /*
  2.  * awk3 -- Builtin functions and various utility procedures 
  3.  *
  4.  * $Log:    awk3.c,v $
  5.  * Revision 1.40  89/03/31  13:17:20  david
  6.  * GNU license; be careful about types in sprintf calls
  7.  * 
  8.  * Revision 1.39  89/03/29  14:20:07  david
  9.  * delinting and code movement
  10.  * change redirect() to return struct redirect *
  11.  * 
  12.  * Revision 1.38  89/03/22  22:10:20  david
  13.  * a cleaner way to handle assignment to $n where n > 0
  14.  * 
  15.  * Revision 1.37  89/03/21  10:54:21  david
  16.  * cleanup and fix of handling of precision in format string of printf call
  17.  * 
  18.  * Revision 1.36  89/03/15  22:01:51  david
  19.  * ENVIRON fix from hack
  20.  * relegated -Ft to strict compatibility
  21.  * getline error return fix
  22.  * printf %c fix (only print 1 char of a string)
  23.  * tolower & toupper added
  24.  * /dev/fd/N etc special files added
  25.  * 
  26.  * Revision 1.35  89/03/15  21:34:05  david
  27.  * try to free more memory
  28.  * 
  29.  * Revision 1.34  88/12/13  22:28:10  david
  30.  * temporarily #ifdef out flush_io in redirect(); adjust atan2() for 
  31.  * force_number as a macro
  32.  * 
  33.  * Revision 1.32  88/12/01  15:03:21  david
  34.  * renamed hack_print_node to do_print (at last!)
  35.  * moved force_string() up out of print_simple for simplicity
  36.  * 
  37.  * Revision 1.31  88/11/30  15:17:27  david
  38.  * free previous value in set_fs
  39.  * 
  40.  * Revision 1.30  88/11/29  16:24:47  david
  41.  * fix bug in previous change
  42.  * 
  43.  * Revision 1.29  88/11/29  15:14:52  david
  44.  * dynamically manage open files/pipes to allow an arbitrary number of open files
  45.  * (i.e. when out of file descriptors, close the least recently used file,
  46.  * saving the current offset; if it is reused, reopen and seek to saved offset)
  47.  * 
  48.  * Revision 1.28  88/11/28  20:12:53  david
  49.  * correct previous error in cleanup of do_substr
  50.  * 
  51.  * Revision 1.27  88/11/23  21:42:13  david
  52.  * Arnold: change ENV to ENVIRON nad a further bug fix for -Ft
  53.  * ..
  54.  * 
  55.  * Revision 1.26  88/11/22  13:50:33  david
  56.  * Arnold: added ENV array and bug fix to -Ft
  57.  * 
  58.  * Revision 1.25  88/11/15  10:24:08  david
  59.  * Arnold: cleanup of comments, #include's and obsolete code
  60.  * 
  61.  * Revision 1.24  88/11/14  21:57:03  david
  62.  * Arnold:  init. FILENAME to "-" and cleanup in do_substr()
  63.  * 
  64.  * Revision 1.23  88/11/01  12:17:45  david
  65.  * cleanu and code movement; changes to reflect change to parse_fields()
  66.  * 
  67.  * Revision 1.22  88/10/19  21:58:43  david
  68.  * replace malloc and realloc with error checking versions
  69.  * 
  70.  * Revision 1.21  88/10/17  20:55:31  david
  71.  * SYSV --> USG
  72.  * 
  73.  * Revision 1.20  88/10/13  21:59:55  david
  74.  * purge FAST and cleanup error messages
  75.  * 
  76.  * Revision 1.19  88/10/06  21:54:28  david
  77.  * cleaned up I/O handling
  78.  * 
  79.  * Revision 1.18  88/10/06  15:49:01  david
  80.  * changes from Arnold: be careful about flushing I/O; warn about error on close;
  81.  * return seed from srand
  82.  * 
  83.  * Revision 1.17  88/09/19  20:39:11  david
  84.  * minor cleanup
  85.  * 
  86.  * Revision 1.16  88/08/09  14:55:16  david
  87.  * getline now gets next file properly
  88.  * stupid bug in do_split() fixed
  89.  * substr() now works if second arg. is negative (truncated to 0)
  90.  * 
  91.  * Revision 1.15  88/06/13  18:07:12  david
  92.  * delete -R option
  93.  * cleanup of redirection code [from Arnold]
  94.  * 
  95.  * Revision 1.14  88/06/07  23:41:00  david
  96.  * some paranoid typecasting plus one bug fix:
  97.  * in do_getline(), use stdin if input_file is NULL and ther is no redirection 
  98.  * 
  99.  * Revision 1.13  88/06/06  21:40:49  david
  100.  * oops! got a little overenthusiastic on that last merge
  101.  * 
  102.  * Revision 1.12  88/06/06  11:27:57  david
  103.  * get rid of some obsolete code
  104.  * merge parsing of fields for record input and split()
  105.  * 
  106.  * Revision 1.11  88/06/05  21:00:35  david
  107.  * flush I/O buffers before calling system (fix from Arnold)
  108.  * 
  109.  * Revision 1.10  88/06/05  20:59:26  david
  110.  * local vars. now come off a stack
  111.  * 
  112.  * Revision 1.9  88/06/01  22:08:24  david
  113.  * in split(), ensure that if second arg. is a local var. that the value is 
  114.  * looked up
  115.  * 
  116.  * Revision 1.8  88/05/31  09:30:16  david
  117.  * Arnold's portability fixes to last change in random() stuff
  118.  * 
  119.  * Revision 1.7  88/05/30  09:53:49  david
  120.  * clean up some fatal() calls
  121.  * de-lint the random number code
  122.  * 
  123.  * Revision 1.6  88/05/27  11:06:21  david
  124.  * input_file wasn't getting properly reset after getline
  125.  * 
  126.  * Revision 1.5  88/05/26  22:49:55  david
  127.  * fixed error message for redirection
  128.  * 
  129.  * Revision 1.4  88/05/18  18:20:02  david
  130.  * fixed case where RS==""; record was including a trailing newline
  131.  * 
  132.  * Revision 1.3  88/04/13  17:39:26  david
  133.  * fixed bug in handling of NR and FNR
  134.  * 
  135.  * Revision 1.2  88/04/12  16:04:02  david
  136.  * fixed bug: NF at end of record generated one less field than it should have
  137.  * 
  138.  * Revision 1.1  88/04/08  15:15:07  david
  139.  * Initial revision
  140.  *  Revision 1.7  88/04/08  15:08:48  david bug fix for file
  141.  * descriptor handlin 
  142.  *
  143.  * Revision 1.6  88/04/08  14:48:36  david changes from Arnold Robbins 
  144.  *
  145.  * Revision 1.5  88/03/28  14:13:54  david *** empty log message *** 
  146.  *
  147.  * Revision 1.4  88/03/23  22:17:41  david mostly delinting -- a couple of bug
  148.  * fixes 
  149.  *
  150.  * Revision 1.3  88/03/18  21:00:13  david Baseline -- hoefully all the
  151.  * functionality of the new awk added. Just debugging and tuning to do. 
  152.  *
  153.  * Revision 1.2  87/11/19  14:42:31  david expanded functionality for getline
  154.  * broke out get_a_record() from inrec() so that the former can be used from
  155.  * do_getline add system() builtin and skeletons for many other new builtins 
  156.  *
  157.  * Revision 1.1  87/10/27  15:23:33  david Initial revision 
  158.  *
  159.  */
  160.  
  161. /* 
  162.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  163.  * 
  164.  * This file is part of GAWK, the GNU implementation of the
  165.  * AWK Progamming Language.
  166.  * 
  167.  * GAWK is free software; you can redistribute it and/or modify
  168.  * it under the terms of the GNU General Public License as published by
  169.  * the Free Software Foundation; either version 1, or (at your option)
  170.  * any later version.
  171.  * 
  172.  * GAWK is distributed in the hope that it will be useful,
  173.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  174.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  175.  * GNU General Public License for more details.
  176.  * 
  177.  * You should have received a copy of the GNU General Public License
  178.  * along with GAWK; see the file COPYING.  If not, write to
  179.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  180.  */
  181.  
  182. #include "awk.h"
  183.  
  184. extern int parse_fields();
  185. extern void assoc_clear();
  186. extern NODE *node();
  187.  
  188. #ifdef USG
  189. extern long lrand48();
  190. extern void srand48();
  191. #else
  192. extern void srandom();
  193. extern char *initstate();
  194. extern char *setstate();
  195. extern long random();
  196. #endif
  197.  
  198. static void set_element();
  199. static void get_one();
  200. static void get_two();
  201. static int get_three();
  202. static int a_get_three();
  203. static void close_one();
  204. static int close_fp();
  205. static NODE *spc_var();
  206.  
  207. NODE *do_sprintf();
  208.  
  209. /* These nodes store all the special variables AWK uses */
  210. NODE *FS_node, *NF_node, *RS_node, *NR_node;
  211. NODE *FILENAME_node, *OFS_node, *ORS_node, *OFMT_node;
  212. NODE *FNR_node, *RLENGTH_node, *RSTART_node, *SUBSEP_node;
  213. NODE *ENVIRON_node, *IGNORECASE_node;
  214. NODE *ARGC_node, *ARGV_node;
  215.  
  216. /*
  217.  * Set all the special variables to their initial values.
  218.  */
  219. void
  220. init_vars()
  221. {
  222. /*** APPEND AFTER 221 IN x:awk3.c ***/
  223. #ifdef AMIGA
  224.     char **environ = NULL;
  225. #else
  226. /*** APPEND AFTER 221 IN x:awk3.c ***/
  227.     extern char **environ;
  228. /*** APPEND AFTER 222 IN x:awk3.c ***/
  229. #endif
  230. /*** APPEND AFTER 222 IN x:awk3.c ***/
  231.     char *var, *val;
  232.     NODE **aptr;
  233.     int i;
  234.  
  235.     FS_node = spc_var("FS", make_string(" ", 1));
  236.     NF_node = spc_var("NF", make_number(-1.0));
  237.     RS_node = spc_var("RS", make_string("\n", 1));
  238.     NR_node = spc_var("NR", make_number(0.0));
  239.     FNR_node = spc_var("FNR", make_number(0.0));
  240.     FILENAME_node = spc_var("FILENAME", make_string("-", 1));
  241.     OFS_node = spc_var("OFS", make_string(" ", 1));
  242.     ORS_node = spc_var("ORS", make_string("\n", 1));
  243.     OFMT_node = spc_var("OFMT", make_string("%.6g", 4));
  244.     RLENGTH_node = spc_var("RLENGTH", make_number(0.0));
  245.     RSTART_node = spc_var("RSTART", make_number(0.0));
  246.     SUBSEP_node = spc_var("SUBSEP", make_string("\034", 1));
  247.     IGNORECASE_node = spc_var("IGNORECASE", make_number(0.0));
  248.  
  249.     ENVIRON_node = spc_var("ENVIRON", Nnull_string);
  250.     for (i = 0; environ[i]; i++) {
  251.         static char nullstr[] = "";
  252.  
  253.         var = environ[i];
  254.         val = index(var, '=');
  255.         if (val)
  256.             *val++ = '\0';
  257.         else
  258.             val = nullstr;
  259.         aptr = assoc_lookup(ENVIRON_node, tmp_string(var, strlen (var)));
  260.         *aptr = make_string(val, strlen (val));
  261.  
  262.         /* restore '=' so that system() gets a valid environment */
  263.         if (val != nullstr)
  264.             *--val = '=';
  265.     }
  266. }
  267.  
  268. /*
  269.  * OFMT is special because we don't dare use force_string on it for fear of
  270.  * infinite loops.  Thus, if it isn't a string, we return the default "%.6g"
  271.  * This may or may not be the right thing to do, but its the easiest 
  272.  */
  273. /* This routine isn't used!  It should be.  */
  274. #ifdef notdef
  275. char *
  276. get_ofmt()
  277. {
  278.     register NODE *tmp;
  279.  
  280.     tmp = OFMT_node->var_value;
  281.     if ((tmp->type != Node_string && tmp->type != Node_str_num) || tmp->stlen == 0)
  282.         return "%.6g";
  283.     return tmp->stptr;
  284. }
  285. #endif
  286.  
  287. char *
  288. get_fs()
  289. {
  290.     register NODE *tmp;
  291.  
  292.     tmp = force_string(FS_node->var_value);
  293.     if (tmp->stlen == 0)
  294.         return 0;
  295.     return tmp->stptr;
  296. }
  297.  
  298. void
  299. set_fs(str)
  300. char *str;
  301. {
  302.     register NODE **tmp;
  303.  
  304.     tmp = get_lhs(FS_node, 0);
  305.     /*
  306.      * Only if in full compatibility mode check for the stupid special
  307.      * case so -F\t works as documented in awk even though the shell
  308.      * hands us -Ft.  Bleah!
  309.      */
  310.     if (strict && str[0] == 't' && str[1] == '\0')
  311.         str[0] = '\t';
  312.     *tmp = make_string(str, 1);
  313.     do_deref();
  314. }
  315.  
  316. /* Builtin functions */
  317. NODE *
  318. do_exp(tree)
  319. NODE *tree;
  320. {
  321.     NODE *tmp;
  322.     double exp();
  323.  
  324.     get_one(tree, &tmp);
  325.     return tmp_number((AWKNUM)exp((double)force_number(tmp)));
  326. }
  327.  
  328. NODE *
  329. do_index(tree)
  330. NODE *tree;
  331. {
  332.     NODE *s1, *s2;
  333.     register char *p1, *p2;
  334.     register int l1, l2;
  335.  
  336.     get_two(tree, &s1, &s2);
  337.     p1 = s1->stptr;
  338.     p2 = s2->stptr;
  339.     l1 = s1->stlen;
  340.     l2 = s2->stlen;
  341.     while (l1) {
  342.         if (STREQN(p1, p2, l2))
  343.             return tmp_number((AWKNUM) (1 + s1->stlen - l1));
  344.         l1--;
  345.         p1++;
  346.     }
  347.     return tmp_number((AWKNUM) 0.0);
  348. }
  349.  
  350. NODE *
  351. do_int(tree)
  352. NODE *tree;
  353. {
  354.     NODE *tmp;
  355.     double floor();
  356.  
  357.     get_one(tree, &tmp);
  358.     return tmp_number((AWKNUM)floor((double)force_number(tmp)));
  359. }
  360.  
  361. NODE *
  362. do_length(tree)
  363. NODE *tree;
  364. {
  365.     NODE *tmp;
  366.  
  367.     get_one(tree, &tmp);
  368.     return tmp_number((AWKNUM) (force_string(tmp)->stlen));
  369. }
  370.  
  371. NODE *
  372. do_log(tree)
  373. NODE *tree;
  374. {
  375.     NODE *tmp;
  376.     double log();
  377.  
  378.     get_one(tree, &tmp);
  379.     return tmp_number((AWKNUM)log((double)force_number(tmp)));
  380. }
  381.  
  382. void
  383. do_printf(tree)
  384. NODE *tree;
  385. {
  386.     register FILE *fp = stdout;
  387.     int errflg = 0;        /* not used, sigh */
  388.  
  389.     if (tree->rnode)
  390.         fp = redirect(tree->rnode, &errflg)->fp;
  391.     if (fp)
  392.         print_simple(do_sprintf(tree->lnode), fp);
  393. }
  394.  
  395. static void
  396. set_element(num, s, len, n)
  397. int num;
  398. char *s;
  399. int len;
  400. NODE *n;
  401. {
  402.     *assoc_lookup(n, tmp_number((AWKNUM) (num))) = make_string(s, len);
  403. }
  404.  
  405. NODE *
  406. do_split(tree)
  407. NODE *tree;
  408. {
  409.     NODE *t1, *t2, *t3;
  410.     register char *splitc;
  411.     char *s;
  412.     NODE *n;
  413.  
  414.     if (a_get_three(tree, &t1, &t2, &t3) < 3)
  415.         splitc = get_fs();
  416.     else
  417.         splitc = force_string(t3)->stptr;
  418.  
  419.     n = t2;
  420.     if (t2->type == Node_param_list)
  421.         n = stack_ptr[t2->param_cnt];
  422.     if (n->type != Node_var && n->type != Node_var_array)
  423.         fatal("second argument of split is not a variable");
  424.     assoc_clear(n);
  425.  
  426.     tree = force_string(t1);
  427.  
  428.     s = tree->stptr;
  429.     return tmp_number((AWKNUM)
  430.         parse_fields(HUGE, &s, tree->stlen, splitc, set_element, n));
  431. }
  432.  
  433. /*
  434.  * Note that the output buffer cannot be static because sprintf may get
  435.  * called recursively by force_string.  Hence the wasteful alloca calls 
  436.  */
  437.  
  438. /* %e and %f formats are not properly implemented.  Someone should fix them */
  439. NODE *
  440. do_sprintf(tree)
  441. NODE *tree;
  442. {
  443. #define bchunk(s,l) if(l) {\
  444.     if((l)>ofre) {\
  445.       char *tmp;\
  446.       tmp=(char *)alloca(osiz*2);\
  447.       bcopy(obuf,tmp,olen);\
  448.       obuf=tmp;\
  449.       ofre+=osiz;\
  450.       osiz*=2;\
  451.     }\
  452.     bcopy(s,obuf+olen,(l));\
  453.     olen+=(l);\
  454.     ofre-=(l);\
  455.   }
  456.  
  457.     /* Is there space for something L big in the buffer? */
  458. #define chksize(l)  if((l)>ofre) {\
  459.     char *tmp;\
  460.     tmp=(char *)alloca(osiz*2);\
  461.     bcopy(obuf,tmp,olen);\
  462.     obuf=tmp;\
  463.     ofre+=osiz;\
  464.     osiz*=2;\
  465.   }
  466.  
  467.     /*
  468.      * Get the next arg to be formatted.  If we've run out of args,
  469.      * return "" (Null string) 
  470.      */
  471. #define parse_next_arg() {\
  472.   if(!carg) arg= Nnull_string;\
  473.   else {\
  474.       get_one(carg,&arg);\
  475.     carg=carg->rnode;\
  476.   }\
  477.  }
  478.  
  479.     char *obuf;
  480.     int osiz, ofre, olen;
  481.     static char chbuf[] = "0123456789abcdef";
  482.     static char sp[] = " ";
  483.     char *s0, *s1;
  484.     int n0;
  485.     NODE *sfmt, *arg;
  486.     register NODE *carg;
  487.     long fw, prec, lj, alt, big;
  488.     long *cur;
  489.     long val;
  490.     unsigned long uval;
  491.     int sgn;
  492.     int base;
  493.     char cpbuf[30];        /* if we have numbers bigger than 30 */
  494.     char *cend = &cpbuf[30];/* chars, we lose, but seems unlikely */
  495.     char *cp;
  496.     char *fill;
  497.     double tmpval;
  498.     char *pr_str;
  499.     extern char *gcvt();
  500.  
  501.  
  502.     obuf = (char *) alloca(120);
  503.     osiz = 120ticsrnen =a los voiddo_spi    El compatibility modepodeps) 
  504.      */
  505. #defility\
  506.   t1);
  507.  
  508.     s g=carg
  509. Ae sp(s0ptr;
  510. ist)    NO    p2 = s_el0ptr;    NO    p2 *s;
  511. el0-- >        rhile (l1) {
  512.     (n->'%/░lca calls 
  513.  *l╡Hmeturn tmûn = U=I╛- >        rhile (l1) {
  514.     (n->'%p    /*
  515.         return 0;
  516.     ri(cha nd =0);
  517. }
  518. *obul;
  519.     r Eility mspret3)-ty ms , &s, tree->stlen, splitc, set_elemevalemeofrec, set_ *gcn->'xterr *) allocU pomspreo_int
  520. ) {s╚aueP w, pr!l0phksize(l)  if((l)>ofre) {\
  521.     char *tmp;heck f
  522.         f(mber([        f7dne perr c *) allocU pomspreo_inc *) allocU pomspreoErea     f7,tmr6osiz*=2;\ \ \tL┘eufe, &tmp);
  523.     return tmp_number((AWKNUM)log((double)force_n sp(
  524.     sll_rU pomspreo n0;
  525.     R;\ \4,}7p);
  526.     reublespli-    sl░lcp);
  527.     returnrint();
  528.  
  529. e perr irg to be formatted.  If we(urnrint();r * pomnf we(urn
  530. e ormattr
  531.     retur;
  532. eashould h
  533.     osiz Tre) {\
  534.    ftiomn sp(
  535.     sll_rU pomspreo n los{s╚auAep[] = " ";
  536.     char *s0o})force_n_numbu2atisu.òu->stlec, ) {\
  537.  Y arg}bbufe(urn
  538. e ormattr
  539.     retur;
  540. eashould h
  541.     en{\
  542.  bosizo2force_strinB    retur;
  543.  thaxterr *freo_isp(
  544.     har *tm
  545.  
  546.     ifelse {\
  547.       get_one(carg,&arg);\
  548.     carg=carg->rnodG}
  549.  
  550. /*tc, u;z*=2;\ \ \t=gram_xter\
  551.   *Og->rnodwa) {*b3.copyRre) {(osio n l *)al
  552.         rn l *gram_xter\
  553.   *Og->rnodwa) {*b3.copyRre) {(osio n}\
  554.   f7dne perr c9osio{(osi am_xter\
  555.   *Og->rnodwa) {*b3.copyRre) {4l
  556. vmp=(c  ╚ fi g()    reuodG}
  557.  
  558. o n0;
  559.     R = o}
  560.     rernoe orma  ofre o}
  561. aps{*b3.auhity e) {o}
  562.     {*b3.aeasho≤2tertaf(c  ╚ fwformattïontb.v9e(us
  563.     char *s0e, &tmp);
  564.     return tmp_number(v9e(us
  565.     charb(osihe plUpf=tmp'cop╞6d.  IIc:Fstrip(s-s{*b3.auhity e) {o}
  566.     {*b3.aeasho≤2tertaf(c  ╚ fwforma
  567.  
  568.     if (a_ge.GetO+ set_ *re ) {*b3.r * formats are note/vntb.v9e(us
  569.     char *s0e, &tmp);
  570.     rg,&a o}
  571.         rn l (us
  572.     cRcsis{s, &the buf9 4re(us
  573.     char *s0e, &t:gcchar *swftmp_numbeΣNUar z b╚ttere(:o_intuf9 4re(use bc,tmr6*fre1&cpbufe bcne⌠rg->rterneosi am_xtcfcne⌠rg->rterneosc{*b3tc,C    if (a_ge.Getk╬r\
  574.  5rgtfpoms  ftirR    R = o}
  575.     rernoe ormal G_b.v9o61 e ormal emop╞6) {\ n-Gtp;hC*b3urntloe+=osiz;\Fcopjz Tre) {\
  576.    ftiomn sp am# b((l)>ofnumber((=(c  ╚ fi g()    reuodG}
  577.  
  578. o n0;
  579.     R ²im\(l)> b.vcopja:gccharab(osib3urr chbuf[] = "012345678ôc  ╚ fi g{
  580.     (n->'%e) {e'%e)ps0ha9osio{(oact  Iiomn sp am# b((l5rgtfpGetrz;\Fcopjz Tre) {\
  581.    ftiomn sp am# b((l)>ofnumber((=(c   arg to be f=E *sfmdef";
  582.     static char sp[] = " ";
  583.     char *s0, *s1;
  584.     int nae:tc, sfmdef"errrlyp    9sp abaasternod(a_grnod    chasam# b(plf";
  585.     st(veems f∙ne⌠rg->rternp = p)forc
  586.  
  587. /DreCy╞6) ucaktoe o}
  588.         rn l (us
  589.     cRcsis{s,aog lhs = tò
  590.     st(veems fn;
  591.     Ae os0op(scab(om"L+=osii ;
  592.     osiz = {*b3tdtp_nugrnoEargC+=oxer_stec, 3tsam# b(plf";
  593.     st(veems f∙ne⌠rg->"Isg{
  594.     (n->'%e) {e'%e)pj o3ething L big in the b in  hinC+cous
  595. sdo
  596. eate/vntbf(a)_3n;
  597.     tRcsis{s,aog lhs = tò
  598.     st(c3ethin    
  599.     Ae(TO *sctcfe⌠rg->"G    refi nod    oxeg#A
  600. o n0;
  601. mber(vme f=E *sfmdef";
  602. U) i·terr *har *s0e, &t:gcchar *swftmpd1 1";
  603.     z = {∞  olR(oaalrpn1&caS   Asdeps) 
  604.      */
  605. #hE'7(l)>oe olnodr *    rhile (li am_xter\
  606.   *Og->rnodwa) {*b3.copyRre) {4l
  607. vmp=(c  ╚ fi4s-m mber(vmesam arg}ftiomn dwaTg L_nu #hE'7(l)>mGe(phar *s0e, &tmp);
  608.     rg,"eof aus fnEelC( w,do(3ps) 
  609.      */
  610. #hE'7(l)>ol)>iof a,yxter\
  611.  icio     */
  612. #hE'7(l)>ol)cpbufe , &tdxer_stec, 3tsam# b(plf";
  613.     st(veems f∙ne⌠rg->"Isg{
  614.     (n-.an# b(plf";
  615.     sFirhil4xtern ;
  616. ) al:,ifar rn rin t1);
  617. pjz s"Isgcne⌠.v9o61 e RhE'7tò
  618.     OMQσ  se;
  619.  
  620.     s g=RhE'eN61 ep-n;
  621.     o=ca charparrneosie*n sp(
  622.     slintrg->rdxer_stec, 3t!    chasasa1l)>olaseGet the Ksc  ¢d->"G    rr2sovetum_xPnt o long uva[ o}
  623. aprexpS ar rn rin t1);:gct║e(us
  624. π sp(rM╕scab(o;
  625. pjz s"Is0e,pjz s"h²im\t th∞i we(
  626. var 0Ttuef";π sp╖wm_xosi *sctcfe⌠ar *IRapnC+cmveemtf;
  627.     int ovetum_xPv9e(╔ a) 
  628.     st(veems f∙ne⌠rg->rt1vbufe , &tdxer_stec, 3tsam# b(urn
  629. e Err2swaTg ar rnYGtong uveÄRf Errrg}ftiomn dwa4²im\f";dFGeatehar chb e2{*b3-teree:tms f&havs-s fUQ3-te+:gccchb\(lNtlen, splitc, set_elemevaleme    refi nod    oxeg#A
  630. o n0;
  631. wen, sod    oxeg#A
  632. o n0;
  633. mber(vme f=E *sfmdef";
  634. U b(plf"+:gcef";
  635.     staticeg#AUrmalN {\ktp_nugrnoEe5'lo p3ò
  636.     OMQtcne# 9 4re note/vntb.v9e(us
  637.     dwa)vt();
  638.  
  639.  
  640.     obuf = (char *) alloca(120);
  641.     osiz = 120ticg0ticmon7tò
  642.     OMQσ %r chbb
  643. iieI1);
  644. sxer_stec, A
  645. o n0;
  646. wen, sod    oxeg#A
  647. o n0;
  648. mber(vme f=RC=tn  * formats are note/ thswen, sod(ï0;
  649. mbe·te!g->rno(vmeng L bRapnCEa rno(vmpen, sod the Ks:saN {\ktp_nui am_xter\
  650.   *Og->rnFf";πoe/vnt    sl░lcp);no(RdwaTg g->r\e(u:4t f=R 1"rosioo;
  651. pì*scth+:4t f=R 1"RC=δe->stlenrymbernB    rnlrn : 0.tehar chb e2{*b3-C=topyRre) {4lahN {\tum_xPnt o lon%
  652. o n0;Pnt F"eof anI chrgtfps0 Errrg}ftiF"e9 Car 0Ttuef";⌐r *    r b╚ttere(:o_ind ;
  653. ) al:,ifar rn rin t1);
  654. pjz s"Isgcne⌠.v9o61 e RhE'7tò
  655. 2{*b3-C=e) {dxerlng L bokEargC+oe/v((l5rgtfpGetu)>oe Csplitc, set_elemevalemrRdwaTl:,rgC+oe/v(Ye {dxerlng L beh\ktpseGn, sodeg#Ag L bRapnCEa rno(vmpen, sod the Ks:saN {\kts"rgC+=t(v*n Rcch.cov!n dRo("eood(ï->"o e RhEgf∙neer(vN Ks /fnumber((=(c  ╚ fi g()    reuo/vnt    s²star(v,((=(c   a=├mpd1 1";
  656.     a {\tum=R 1"RC=δee2{1"RC=δ  lhs =f, ste0t    char *s0, *s1;
  657.     int2, 3,Ff╚ fi g{
  658.      o l2{1"RC=δ  fi g{
  659.      o loaeuo/vnt    s²star(vl╚ figo}
  660. e Ks:hinCar sp(rM╕scab(o;
  661. pjd-ÿ,peσoae[ s"vitc,:  & & b3.r * formats are note/vntb.v97tò
  662. 2{*b3F"e9#aTgfpsk, &ar *s0,F{*b(no;
  663. π 1e[ r_sn+rf8enIRC=δ  lhs =f, ste0t    )aurtlNtee0t    charG:Ff╚psk,ode/bfAstar(vl╚ figoszo≤ef fic#i     fnEIRapnC+cmveemtf;
  664. rt╔e,rEIRapnC+h\ktpseGnε{\kp-n;
  665.     o=mocha0t    c{dxgi amt o lon%
  666. o n0;Pnt F"eof anI chrgtfps0 Errrg}fRpb(no;
  667. π 1e²st=t(vaTg² anRapnsteote/  naurtlNtee0t    charG:F┌/e2{1"RC=δ  lhWsam#+UMoC ts"foeO╠3 ep═δ  kts"8# b1{
  668.     (aaaaaoo(vmy(l5b3-C╔Re'd chrgtfps0 Er beh\ktpseGn, sodeg#AgNL(v9e(us
  669.     charb(osiheciyarp ";
  670.     char *s0, *s1;
  671. r rn    charG:F┌/e2{1"pssp am#c18n, sg;πol t rtpseGnodeA
  672. o "e)ëiDtpsh, *stb.v9=((=arp lemevSo    charG:NtehA-charG:F┌/e2{1"RC=δ  lhWsam#+0t    co L bRapmeems f∙n0apmeems ehaEateam#+0t    co L ie*n sp(
  673.     slintrg->rc(vl╚:F┌);
  674. pjz s"IsgnC+ntrg->=f, ste0t1);
  675. lp lb(pl;r beh\$(sp(
  676. ae[\ar(2kEar⌠rg-nn :c,t    co L bRap2{1"RC=δ  lhWsam#+0t    co 1Nirhil4xeuodGe⌠ar *Ico 1Nirhil#hE'7(l)te0tf╚ fi :*7orar *IRapnC+Mb24r o lon%
  677. o ndGe⌠b⌐r *    D'lo *Ico b⌐r9s(:,ifL bRap2{uf ?c╓A*s11l:,rgC+n7)te0tf╚ fi :*7orar *IRo:F┌sieAi note/vw1"RC=δ  lhWAifL bRat;
  678. πfvp┬eRap2{1IcoUNe rtp rtp1"p2egcharGa û{\
  679. "RC RC=δ  fiegp1rG:n¿ae/vF    insp(  L 3n-.ar\=f,/vFo nh\=fV₧uvF    insp(  Lfnumm#A
  680. o n0;
  681. mber(vme f=ar pl;vta kts"ci;tare+1ficvTfi g( nC+clNtlco 1    cRcr=((\har'vnte/vF    gC+δ  fi oeatehar chb e2{*b3-teree:tms rb(osiheciyarusod tvl╚ figo}
  682. e Ks:hinCarms dF#e) {rc(vl╚vnt    e0tfktsdF#tpse+clN+ *I    charG:F┌/e+clN+ *I    chahrgtficvTfi g( nC+clNtlcNL bRms rb(on-1:lrpn1&crar charGa nodwa) {Nirtp_nugrnoEargC+=oxer_stec, 3t *IRaòsgcne⌠.v9o61 e RhE'7l#h;
  683. pjz s"I0tf, so rb(o,1oGa nta:4t f=
  684.     n, soo(vmyn_4dxer;dFGsom;⌐r pUI%cnarg(aDçsi *sctcf5rciyarusod, soo(vmvp┬e8I%c+)n"oupjzv:Tc(b⌐r9    gC+nY0    vmvx*⌠b⌐r *    I0tfF    in0 c"eo0ate/p O
  685.     s terëts""e Krn    : soo(vmyn_4dxer;j: 0.tehar    char *sae/vF    ievF    ievFoÑsoo(vmynLliyarusr     CEa rl=7(lhil4,f*ae;n_4dsp(r%c+ chb Bt*    I0tfF    3ivF    gC+δlF#e)?c╓i{1"lcR>Üte Krnte0tA    Θ(Orn    : soo(vmyn_4dxer;j: 0.teha    CElp Oe'd   3 p3solNtl#Ag L bRapaDçsi,f*ckAue) {Puta;πoe/vNloae(b⌐r9    ,sn    : soop1t1);
  686. pjz0ap    4nA:7,>Öare+0vF    gg L bRa    I0tfF    3ivF    gC+δlF#e)?c╓i{1"lcR>Üte Krnte0tA    Θ(Orn    : Gya û{\
  687. "Rs11l3 *s1;rí"lcpRC=δ+FGso pU;pRC=n    :"lcR& 8;pRC=n    ╜ *scttttttttttttediv9e(us
  688. 1;rí"eo0ate/p O
  689.     s te    ╜ *sctvme f=:er;dFG so rb(o,SNu+:gvvp┬eRap2{1eoR2{*b3-tereep$s"I0tf, sgtfpaN {    : Gya insp( C=δbts"cd, so*    I    gg "eo0ate/pm(11"RC=δ  ,Rap2{1In    :┬eRap2e1/vFo yiT=δ  ,Rap2{(vmrí"urt;j: 0.tehar    paC=nvme f=:er;dFG sF    gCrΓeemF    3upaN o rftf, sls1;
  690. 7F    ievhar    dFG sF    gCrΓeemF    3up3
  691. mb fieri :*7orar *IRo:F┌sieAi note/vwer;dFGoe ;uta;:F┌/e2{1"RC=δ  lhWs+n7paCA    Θ(OrtlND{(vmkts,f*ckAue)te Krs =f,El  fi oeatepeσ  fu=f,ES!ÿvF     o r{Puta9(us
  692.     dwa)vt();
  693.  
  694.  
  695.     obuf = ≤vme o=th "eo=th    s²svF     o r{Puta ktuvTf, sls1;Goe ;utu= ≤vme o=th "eo=th    s²Gya û{\
  696. ,"eoC+clNtg"are =th "enehaND{(r'v%&autahnC+clNt1n_4dxerrpGetu)>oe Csplitc, set_elemesoo(vmyn╞Tefs0 E*s1lae;n_4dsp(r%c+ c=th "e & & bF    3up3
  697. mb+ c=tbC+cl3s/oraek9plitc E* L bRa    I0sUûE0EenebC+cl3s/oplitcT=δnA>oe CspF    3upaN o rftfp ;uta;:F┌/cT=δnote/nNtg";
  698. pauRmabRaoo=thrrrg}o *Ico b1c*Goern  bRaRmab e2{*bte0t/,&ar *s0,  fi oen'AAAAvvvvⁿùB8Auufffffffffvvvvvvvvvv8CCCCCCCCCuffffffffffAAAAAAAAAuuuuuuuuuuvvvvvvvvvvvvvvvvvvvvfAAAAAAAAA33333333333333333333333[[[[[[[[[ufffffffffffffffffffffffffffffffv[}\>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]%                                                                                                        =O888888888ffffffffffffAAAAAAAAAueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeefuuuuuuuuupeeeeeeeeeeeeeeeeeeeeeeeee33vRCCCCCCCCCCCCCCCCCCCCfuuuuuuuuueeeeeeeeeeeeeeeeeeeeeeepppppppppeeeeeeeeeeffffffffffffffffpAAAAAAAAAueeeeeeeeeeeeeeeeeeeeeeeO9+BNgC=b3vvvvvvvvvppppppppppuuuuuuuuufeeeeeeeeeeeeeeeeeeeeeeeeeARRRRRRRRRRRRppppppppppppppppppuuuuuuuuueeeeeeeeeeeeeeeeeeeeeeefffffffffee333333333333333333333NNNNNNNNNNNN8bggggggggggggggggggvAAAAAAAAAAAAAAAAfpppppppppueeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeffffffffffuuuuuuuuuReeeeeeeeeeeeeeeeeeeeeeeeeppU5O""""""""""""""""""""""""""""""GC>Y[}%\\\\\\\\\\\\\\\\\\\\\9++++++++++++3bNv8BBBBBBBBBBBBBBBBBBBffffffffffffffffffuuuuuuuuueeeeeeeeeeeeeeeeeeeeeeeRgggggggggeeccccccccccccccccccppppppppppppppppAfffffffffueeeeeeeeeeeeeeeeeeeeeeebbbbbbbbbbbbbbbbbbbbbRRRRRRRRRRRR3ddddddddddNvvvvvvvvvA=cuuuuuuuuupeeeeeeeeeeeeeeeeeeeeeeeeefffffffffffgggggggggcuuuuuuuuueeeeeeeeeeeeeeeeeeeeeeepppppppppeeCU5O"ymbhhhhhhhhhhhhhhhhhG9_38wwwwwwwwwwwwwwwwwwwwwRAAAAAAAAAAAAdNNNNNNNNNNlllllllllcffffffffffffffffpgvvvvvvvvvueeeeeeeeeeeeeeeeeeeeeeeccccccccccccccccccpluuuuuuuuufeeeeeeeeeeeeeeeeeeeeeeeee=++++++++++++++++++++++++++bhhhhhhhhhhh,3mmmmmmmmmmmmmmmmmmmmmRAAAAAAAAAAAAdNgccccccccccpppppppppluuuuuuuuueeeeeeeeeeeeeeeeeeeeeeefffffffffeeeeeeeeeeevvvvvvvvvlccccccccccccccccfpppppppppueeeeeeeeeeeeeeeeeeeeeee*******************************************************************************?5.VW6ëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëëïσ!!!!!!!!!!!!!!!!!!!!!!!Sê|||||||||||||||||||||||||||||||||||||||||||||||||∞ÿ╞j>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$8%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Y[CUB}O"h:99999999999999999yGmmmmmmmmmmmmmmmmmmmmmmmmmm]\_w=bbbbbbbbbbbb,3333333333333333333333333333333333333333RlNAAAAAAAAAfvduuuuuuuuuceeeeeeeeeeeeeeeeeeeeeeeeeppnllllllllllfguuuuuuuuu eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeec         eemmmmmmmmmmmm:h+++++++++++++++++++++b,3vvvvvvvvvvvRNniiiiiiiiiipgAllllllllllllllllcfffffffff          eeeeeeeeeeeeeeeeuuniiiiiiiiiipdlccccccccc eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeef         eeOS5.8w*CUT;"9h0000000000000000000yyyyyyyyyyyyyyyyyG,,,,,,,,,,,,:mRRRRRRRRRRRRRRRRRRRRRb+_u3vigggggggggggpnlllllllllllllllllllllllllfdNNNNNNNNN          eeeeeeeeeeeeeeeecciupnllllllllllfffffffff eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeA         ee:hb,,,,,,,,,,,,0gRRRRRRRRRRRRRRRRRRRRRmc=3udvniiiiiiiiiippppppppppppppppAAAAAAAAAAAlllllllll          eeeeeeeeeeeeeeeeffucniiiiiiiiiipNNNNNNNNN