예제 #1
0
파일: tabscan.c 프로젝트: crubeido/test
int main (int argc, char* argv[])
{                               /* --- main function for testing */
  int     d;                    /* delimiter of current field */
  FILE    *file;                /* file to read */
  TABSCAN *tsc;                 /* table scanner for testing */
  char    buf[256];             /* read buffer */

  if (argc < 2) {               /* if no arguments given, abort */
    printf("usage: %s file\n", argv[0]); return 0; }
  file = fopen(argv[1], "rb");  /* open the input file */
  if (!file) { printf("cannot open %s\n", argv[1]); return -1; }
  tsc = ts_create();            /* create a table scanner */
  if (!tsc)  { printf("not enough memory\n");       return -1; }
  ts_chars(tsc, TS_COMMENT, "#");
  do {                          /* file read loop */
    d = ts_next(tsc, file, buf, sizeof(buf));
    printf("%d : %s\n", d, buf);/* print delimiter and field */
  } while (d >= 0);             /* while not at end of file */
  ts_delete(tsc);               /* delete the table scanner */
  fclose(file);                 /* and close the input file */
  return 0;                     /* return 'ok' */
}  /* main() */
예제 #2
0
static void xskin_jobs( int pipe_in ) {
  XEvent e;
  int x,y;
  int window_x,window_y;
  int fspe=0;
  int pr=-1;
  int z;
  int p;
  int master_volume=0;
  char file_name[1024], tmp[1024];

  int last_puttext_time;
  int last_window_x=-1, last_window_y=-1;

  int max_files;
  int i;
  fd_set fds;
  static struct timeval tv;

  Window t_w;
  unsigned int t_width, t_height, t_border, t_depth;

  xskin_pipe_write( "READY" );

  shmid = shmget( IPC_PRIVATE, sizeof(char)*SPE_W, IPC_CREAT|0600 );
  if ( shmid<0 ) xskin_pipe_write( "ERROR" );
  else {
    sprintf( local_buf, "%d", shmid );
    xskin_pipe_write( local_buf );
    speana_buf = (unsigned char *)shmat( shmid, 0, 0 );
  }

  xskin_pipe_read( local_buf, sizeof(local_buf) );
  max_files = atoi( local_buf );
  for ( i=0 ; i<max_files ; i++ ) {
    xskin_pipe_read( local_buf, sizeof(local_buf) );
  }

  z=1;
  last_puttext_time=0;
  last_current_time=0;

  XGetGeometry( xskin_d, xskin_w, &t_w,
		&window_x, &window_y,
		&t_width, &t_height, &t_border, &t_depth );

  while( z ) {

    XFlush( xskin_d );

    FD_ZERO( &fds );
    FD_SET( pipe_in, &fds );
    tv.tv_sec=0;
    tv.tv_usec=20000L; /* 20 msec */
    i=select( pipe_in+1, &fds, NULL, NULL, &tv );

    if ( i!=0 ) {
      xskin_pipe_read( local_buf, sizeof(local_buf) );
      switch (local_buf[0]) {

      case 'A': /* total time */
	total_time=atoi( local_buf+2 );
	last_current_time=0;
	last_puttext_time=0;
	break;
	
      case 'T': /* current time */
	{
	  int min,sec;
	  sscanf( local_buf+2, "%02d:%02d", &min, &sec );
	  i=min*60+sec;
	  if ( fremain==1 ) {
	    sec =total_time-i;
	    min =sec/60;
	    sec-=min*60;
	  }
	  if ( i != last_current_time ) {
	    ts_putnum( MIN_H_X, MIN_H_Y, min/10 );
	    ts_putnum( MIN_L_X, MIN_L_Y, min%10 );
	    ts_putnum( SEC_H_X, SEC_H_Y, sec/10 );
	    ts_putnum( SEC_L_X, SEC_L_Y, sec%10 );
	    p=100*i/total_time;
	    play_val=ts_pos( OFF, -p );
	    last_current_time=i;

	    if ( last_current_time - last_puttext_time == 3 ) { /* 3 sec */
	      sprintf( tmp, "%s [%02d:%02d]",
		       file_name, total_time/60, total_time%60 );
	      ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	    }
	  }
	}
      break;

      case 'L': /* lylics/message */
	ts_puttext( MESSAGE_X, MESSAGE_Y, local_buf+2 );
	last_puttext_time=last_current_time;
	break;

      case 'F': /* filename */
	strncpy( file_name, local_buf+2, 1023 );
	file_name[1023]=0;
	break;

      case 'O': /* off the play button */
	fplay=0;
	ts_play(OFF);
	ts_spectrum(fspe, NULL); /* erase spectrums */
	break;

      case 'V': /* master volume */
	master_volume=atoi( local_buf+2 );
	p=100*((master_volume<200)?master_volume:200)/200; /* max:200% */
	vol_val=ts_volume( OFF, -p );
	break;

      case 'Q': /* quit */
	z=1;
	break;

      case 'W': /* wave form */
	ts_spectrum(fspe, speana_buf);
	break;

      default:
	break;
      }
    }

    if ( XPending( xskin_d )==0 ) continue;
    XNextEvent( xskin_d, &e );

    switch ( e.type ) {
      /*
    case KeyPress:
      z=0;
      break;
      */
   
    case Expose:
      repaint();
      break;

    case EnterNotify:
      {
	Cursor cs;
	ts_titlebar(ON);
	cs = XCreateFontCursor( xskin_d, XC_top_left_arrow );
	XDefineCursor( xskin_d, xskin_w, cs );
      }
      break;

    case LeaveNotify:
      ts_titlebar(OFF);
      XUndefineCursor( xskin_d, xskin_w );
      break;

    case MotionNotify:
      while( XCheckMaskEvent( xskin_d, Button1MotionMask, &e ) ) {
	XNextEvent( xskin_d, &e );
      }
      x = e.xbutton.x;
      y = e.xbutton.y;
      switch( pr ) {
	
	/*
      case TS_POS:
	play_val=ts_pos( ON, x );break;
	*/
      case TS_VOLUME:
	vol_val=ts_volume( ON, x );
	i=master_volume;
	master_volume=200*vol_val/100;
	sprintf( local_buf, "V %d", master_volume-i );
	xskin_pipe_write( local_buf );

	sprintf( tmp, " volume: %d%%", vol_val );
	ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	last_puttext_time=last_current_time;
	break;
	/*
      case TS_PAN:
	pan_val=ts_pan( ON, x );break;
	*/
	
      default:
	if ( x != last_window_x || y != last_window_y ) {
	  window_x += x-last_window_x;
	  window_y += y-last_window_y;
	  XMoveWindow( xskin_d, xskin_w,
		       window_x, window_y );
	}
	break;
      }
      break;

    case ButtonPress:
      x = e.xbutton.x;
      y = e.xbutton.y;
      last_window_x=x;
      last_window_y=y;

             if ( ISIN( x, y,EXITBUTTON_DX,EXITBUTTON_DY,
			EXITBUTTON_W,EXITBUTTON_H ) ) {
        ts_exitbutton(ON);pr=TS_EXITBUTTON;

      } else if ( ISIN( x, y, PREV_DX, PREV_DY, PREV_W, PREV_H ) ) {
	ts_prev(ON);pr=TS_PREV;
      } else if ( ISIN( x, y, PLAY_DX, PLAY_DY, PLAY_W, PLAY_H ) ) {
	ts_play(ON);pr=TS_PLAY;
      } else if ( ISIN( x, y, PAUSE_DX, PAUSE_DY, PAUSE_W, PAUSE_H ) ) {
	ts_pause(ON);pr=TS_PAUSE;
      } else if ( ISIN( x, y, STOP_DX, STOP_DY, STOP_W, STOP_H ) ) {
	ts_stop(ON);pr=TS_STOP;
      } else if ( ISIN( x, y, NEXT_DX, NEXT_DY, NEXT_W, NEXT_H ) ) {
	ts_next(ON);pr=TS_NEXT;
      } else if ( ISIN( x, y, EJECT_DX, EJECT_DY, EJECT_W, EJECT_H ) ) {
	ts_eject(ON);pr=TS_EJECT;

      } else if ( ISIN( x, y,164, 89, 47, 15 ) ) {  /* shuffle */
	if ( fshuf==0 ) {
	  ts_shuf(OFFON);pr=TS_SHUFON;
	} else { 
	  ts_shuf(ONOFF);pr=TS_SHUFOFF;
	}
      } else if ( ISIN( x, y,210, 89, 28, 15 ) ) {  /* repeat */
	if ( frep==0 ) {
	  ts_rep(OFFON);pr=TS_REPON;
	} else {
	  ts_rep(ONOFF);pr=TS_REPOFF;
	}
      } else if ( ISIN( x, y,219, 58, 23, 12 ) ) {  /* equalizer */
	if ( fequ==0 ) {
	  ts_equ(OFFON);pr=TS_EQUON;
	} else {
	  ts_equ(ONOFF);pr=TS_EQUOFF;
	}
      } else if ( ISIN( x, y,242, 58, 23, 12 ) ) {  /* playlist */
	if ( fpll==0 ) {
	  ts_plist(OFFON);pr=TS_PLISTON;
	} else {
	  ts_plist(ONOFF);pr=TS_PLISTOFF;
	}

      } else if ( ISIN( x, y, MENUBUTTON_DX, MENUBUTTON_DY,
			MENUBUTTON_W, MENUBUTTON_H ) ) {
	ts_menubutton(ON);pr=TS_MENUBUTTON;
      } else if ( ISIN( x, y, ICONBUTTON_DX, ICONBUTTON_DY,
			ICONBUTTON_W, ICONBUTTON_H ) ) {
	ts_iconbutton(ON);pr=TS_ICONBUTTON;
      } else if ( ISIN( x, y, MINIBUTTON_DX, MINIBUTTON_DY,
			MINIBUTTON_W, MINIBUTTON_H ) ) {
	ts_minibutton(ON);pr=TS_MINIBUTTON;

	/*
      }	else if ( ISIN( x, y,POS_MIN_DX+(POS_MAX_DX-POS_MIN_DX)*play_val/100,
			POS_DY, POS_W, POS_H ) ) {
	ts_pos( ON, -play_val );pr=TS_POS;
	*/
      } else if ( ISIN( x, y,VOL_MIN_DX+(VOL_MAX_DX-VOL_MIN_DX)*vol_val/100,
			VOL_DY, VOL_W, VOL_H ) ) {
	ts_volume( ON, -vol_val );pr=TS_VOLUME;
	sprintf( tmp, " volume: %d%%", vol_val );
	ts_puttext( MESSAGE_X, MESSAGE_Y, tmp );
	last_puttext_time=last_current_time;

	/*
      } else if ( ISIN( x, y,PAN_MIN_DX+(PAN_MAX_DX-PAN_MIN_DX)*pan_val/100,
			PAN_DY, PAN_W, PAN_H ) ) {
	ts_pan( ON, -pan_val );pr=TS_PAN;
	*/

      } else if ( ISIN( x, y, MIN_H_X, MIN_H_Y,
			SEC_L_X+NUM_W-MIN_H_X, NUM_H ) ) {
	int min,sec;
	fremain=(fremain==0)?1:0;
	sec=(fremain==0)?last_current_time:total_time-last_current_time;
	min =sec/60;
	sec-=min*60;
	ts_putnum( MIN_H_X, MIN_H_Y, min/10 );
	ts_putnum( MIN_L_X, MIN_L_Y, min%10 );
	ts_putnum( SEC_H_X, SEC_H_Y, sec/10 );
	ts_putnum( SEC_L_X, SEC_L_Y, sec%10 );

      } else if ( ISIN( x, y, SPE_SX, SPE_SY, SPE_W, SPE_H ) ) {
	pr=TS_SPECTRUM;
      } else {
	XRaiseWindow( xskin_d, xskin_w );
      }
	     break;  

    case ButtonRelease:

      last_window_x = -1;
      last_window_y = -1;

      switch( pr ) {

      case TS_EXITBUTTON:
	ts_exitbutton(OFF);
	xskin_pipe_write("Q");
	z=0;break;

      case TS_PREV:
	ts_prev(OFF);
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("B");
	break;
      case TS_PLAY:
	xskin_pipe_write("P");
	fplay=1;
	pauseOff();
	ts_play(OFF);ts_pause(OFF);
	ts_pstate( PSTATE_PLAY );
	break;
      case TS_PAUSE:
	ts_pause(OFF);
	if ( fplay ==1 ) {
	  if ( fpause==0 ) {
	    ts_pstate( PSTATE_PAUSE );
	    ts_spectrum( fspe, NULL );
	    pauseOn();
	  } else {
	    ts_pstate( PSTATE_PLAY );
	    pauseOff();
	  }
	}
	break;
      case TS_STOP:
	pauseOff();
	fplay=0;
	ts_pause(OFF);ts_play(OFF);ts_stop(OFF);
	ts_pstate( PSTATE_STOP );
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("S");
	break;
      case TS_NEXT:
	ts_next(OFF);
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("N");
	break;
      case TS_EJECT:
	ts_eject(OFF);break;

      case TS_SHUFON:
	ts_shuf(ON);fshuf=1;
	fplay=1;
	pauseOff();
	ts_pstate( PSTATE_PLAY );
	xskin_pipe_write("D 1");
	break;
      case TS_SHUFOFF:
	ts_shuf(OFF);fshuf=0;
	fplay=0;
	pauseOff();
	ts_pstate( PSTATE_STOP );
	ts_spectrum( fspe, NULL );
	xskin_pipe_write("D 2");
	break;
      case TS_REPON:
	ts_rep(ON);frep=1;
	xskin_pipe_write("R 1");
	break;
      case TS_REPOFF:
	ts_rep(OFF);frep=0;
	xskin_pipe_write("R 0");
	break;

      case TS_EQUON:
	ts_equ(ON);fequ=1;break;
      case TS_EQUOFF:
	ts_equ(OFF);fequ=0;break;

      case TS_PLISTON:
	ts_plist(ON);fpll=1;break;
      case TS_PLISTOFF:
	ts_plist(OFF);fpll=0;break;

      case TS_MENUBUTTON:
	ts_menubutton(OFF);break;
      case TS_ICONBUTTON:
	ts_iconbutton(OFF);break;
      case TS_MINIBUTTON:
	ts_minibutton(OFF);break;

	/*
      case TS_POS:
	ts_pos( OFF, -play_val );break;
	*/
      case TS_VOLUME:
	ts_volume( OFF, -vol_val );break;
	/*
      case TS_PAN:
	ts_pan( OFF, -pan_val );break;
	*/

      case TS_SPECTRUM:
#ifdef SUPPORT_SOUNDSPEC
	fspe = (fspe+1)%3;
	if ( fspe==1 ) xskin_pipe_write("W");      /* on */
	else if ( fspe==0 ) {
	  xskin_pipe_write("W"); /* off */
	  ts_spectrum(0,speana_buf);
	}
#endif /* SUPPORT_SOUNDSPEC */
	break;

      default:
	break;
      }
      pr=-1;
      break;

    default:
      break;
    }
  }

  return;
}
예제 #3
0
static void repaint( void ) {

  char tmp[64];
  int min,sec;

  /* static values */

  XClearWindow( xskin_d, xskin_w );

  ts_titlebar(OFF);

  ts_prev(OFF);
  ts_play(OFF);
  ts_pause(OFF);
  ts_stop(OFF);
  ts_next(OFF);
  ts_eject(OFF);

  if ( (play_mode->encoding & PE_MONO)==0 ) {
    ts_mono(OFF);
    ts_stereo(ON);
  } else {
    ts_mono(ON);
    ts_stereo(OFF);
  }

  ts_pan(OFF,-50);
  ts_puttext( BITRATE_X, BITRATE_Y, "---" ); /* bit-rate */
  
  sprintf( tmp, "%d", (int)play_mode->rate/1000 );
  ts_puttext( SAMPLE_X,  SAMPLE_Y,  tmp  ); /* sample-rate */

  /* volatile values */

  if ( fshuf==0 ) ts_shuf(OFF);
  else ts_shuf(ON);

  if ( frep==0 ) ts_rep(OFF);
  else ts_rep(ON);

  if ( fequ==0 ) ts_equ(OFF);
  else ts_equ(ON);

  if ( fpll==0 ) ts_plist(OFF);
  else ts_plist(ON);

  if ( fplay==1 ) {
    if ( fpause==0 ) ts_pstate( PSTATE_PLAY );
    else  ts_pstate( PSTATE_PAUSE );
  } else ts_pstate( PSTATE_STOP );

  ts_volume( OFF, -vol_val );
  ts_pos( OFF, -play_val );

  ts_puttext( MESSAGE_X, MESSAGE_Y, last_text );

  if ( fremain==0 ) {
    sec=last_current_time;
  } else {
    sec=total_time-last_current_time;
  }
  min =sec/60;
  sec-=min*60;

  ts_putnum( MIN_H_X, MIN_H_Y, min/10 );
  ts_putnum( MIN_L_X, MIN_L_Y, min%10 );
  ts_putnum( SEC_H_X, SEC_H_Y, sec/10 );
  ts_putnum( SEC_L_X, SEC_L_Y, sec%10 );

  XFlush(xskin_d);
  return;
}
예제 #4
0
int main (int argc, char *argv[])
{                               /* --- main function */
  int    i, k = 0;              /* loop variables, counters */
  char   *s;                    /* to traverse options */
  char   **optarg = NULL;       /* option argument */
  char   *fn_hdr  = NULL;       /* name of table header file */
  char   *fn_tab  = NULL;       /* name of table file */
  char   *fn_frq  = NULL;       /* name of frequency file */
  char   *fn_out  = NULL;       /* name of output file */
  char   *blanks  = NULL;       /* blank  characters */
  char   *fldseps = NULL;       /* field  separators */
  char   *recseps = NULL;       /* record separators */
  char   *nullchs = NULL;       /* null value characters */
  char   *comment = NULL;       /* comment characters */
  char   *clsname = NULL;       /* name of class column to balance */
  int    inflags  = 0;                 /* table file read  flags */
  int    outflags = AS_ATT|AS_WEIGHT;  /* table file write flags */
  double wgtsum   = 0;          /* weight of tuples in output table */
  int    valcnt;                /* number of attribute values */
  int    clsid;                 /* id of class column */
  ATT    *att;                  /* class attribute */
  int    d;                     /* delimiter type */

  prgname = argv[0];            /* get program name for error msgs. */

  /* --- print startup/usage message --- */
  if (argc > 1) {               /* if arguments are given */
    fprintf(stderr, "%s - %s\n", argv[0], DESCRIPTION);
    fprintf(stderr, VERSION); } /* print a startup message */
  else {                        /* if no argument is given */
    printf("usage: %s [options] [-q frqfile] "
                     "[-d|-h hdrfile] tabfile outfile\n", argv[0]);
    printf("%s\n", DESCRIPTION);
    printf("%s\n", VERSION);
    printf("-c#      name of field to balance (default: last field)\n");
    printf("-s#      sum of tuple weights in output table "
                    "(default: as in input table)\n");
    printf("         (-2: lower, -1: boost, 0: shift weights)\n");
    printf("-q       adjust to relative frequencies stated in frqfile\n");
    printf("frqfile  file containing value/relative frequency pairs\n");
    printf("-a       align fields of output table "
                    "(default: do not align)\n");
    printf("-w       do not write field names to output file\n");
    printf("-b#      blank   characters    (default: \" \\t\\r\")\n");
    printf("-f#      field   separators    (default: \" \\t\")\n");
    printf("-r#      record  separators    (default: \"\\n\")\n");
    printf("-C#      comment characters    (default: \"#\")\n");
    printf("-u#      null value characters (default: \"?*\")\n");
    printf("-n       number of tuple occurrences in last field\n");
    printf("-d       use default header "
                    "(field names = field numbers)\n");
    printf("-h       read table header (field names) from hdrfile\n");
    printf("hdrfile  file containing table header (field names)\n");
    printf("tabfile  table file to read "
                    "(field names in first record)\n");
    printf("outfile  file to write output table to\n");
    return 0;                   /* print a usage message */
  }                             /* and abort the program */

  /* --- evaluate arguments --- */
  for (i = 1; i < argc; i++) {  /* traverse arguments */
    s = argv[i];                /* get option argument */
    if (optarg) { *optarg = s; optarg = NULL; continue; }
    if ((*s == '-') && *++s) {  /* -- if argument is an option */
      while (1) {               /* traverse characters */
        switch (*s++) {         /* evaluate option */
          case 'c': optarg    = &clsname;      break;
          case 's': wgtsum    = strtod(s, &s); break;
          case 'q': optarg    = &fn_frq;       break;
          case 'a': outflags |= AS_ALIGN;      break;
          case 'w': outflags &= ~AS_ATT;       break;
  	  case 'b': optarg    = &blanks;       break;
          case 'f': optarg    = &fldseps;      break;
          case 'r': optarg    = &recseps;      break;
          case 'u': optarg    = &nullchs;      break;
          case 'C': optarg    = &comment;      break;
          case 'n': inflags  |= AS_WEIGHT;     break;
          case 'd': inflags  |= AS_DFLT;       break;
          case 'h': optarg    = &fn_hdr;       break;
          default : error(E_OPTION, *--s);     break;
        }                       /* set option variables */
        if (!*s) break;         /* if at end of string, abort loop */
        if (optarg) { *optarg = s; optarg = NULL; break; }
      } }                       /* get option argument */
    else {                      /* -- if argument is no option */
      switch (k++) {            /* evaluate non-option */
        case  0: fn_tab = s;      break;
        case  1: fn_out = s;      break;
        default: error(E_ARGCNT); break;
      }                         /* note filenames */
    }
  }
  if (optarg) error(E_OPTARG);  /* check option argument */
  if (k != 2) error(E_ARGCNT);  /* check number of arguments */
  if (fn_hdr) {                 /* set header flags */
    inflags = AS_ATT | (inflags & ~AS_DFLT);
    if (strcmp(fn_hdr, "-") == 0) fn_hdr = "";
  }                             /* convert "-" to "" */

  /* --- read table header --- */
  attset = as_create("domains", att_delete);
  if (!attset) error(E_NOMEM);  /* create an attribute set */
  as_chars(attset, recseps, fldseps, blanks, nullchs, comment);
  fprintf(stderr, "\n");        /* set delimiter characters */
  in = io_hdr(attset, fn_hdr, fn_tab, inflags, 1);
  if (!in) error(1);            /* read the table header */

  /* --- determine id of class attribute --- */
  if (!clsname)                 /* if no class attribute name given, */
    clsid = as_attcnt(attset) -1;     /* use last column as class */
  else {                        /* if class attribute name is given */
    if ((clsid = as_attid(attset, clsname)) < 0) {
      s = (inflags & AS_ATT) ? fn_hdr : fn_tab;
      io_error(E_MISFLD, s, 1, clsname); error(1);
    }                           /* check whether class exists */
  }                             /* and abort on error */

  /* --- read table --- */
  table = io_bodyin(attset, in, fn_tab, inflags, "table", 1);
  in    = NULL;                 /* read the table and */
  if (!table) error(1);         /* check for an error */

  /* --- balance frequencies --- */
  if (fn_frq) {                 /* if frequencies are given */
    if (*fn_frq)                /* if a proper file name is given, */
      in = fopen(fn_frq, "rb"); /* open frequency file for reading */
    else {                      /* if no proper file name is given, */
      in = stdin; fn_frq = "<stdin>"; } /* read from standard input */
    fprintf(stderr, "reading %s ... ", fn_frq);
    if (!in) error(E_FOPEN, fn_frq);
    att    = as_att(attset, clsid);
    valcnt = att_valcnt(att);   /* get att. and number of values */
    freqs  = (double*)malloc(valcnt *sizeof(double));
    if (!freqs) error(E_NOMEM); /* allocate a frequency vector */
    for (i = valcnt; --i >= 0; ) freqs[i] = 1.0F;
    for (k = 0; 1; k++) {       /* frequency read loop */
      d = ts_next(as_tabscan(attset), in, buf, AS_MAXLEN);
      if (d <= TS_EOF) {        /* read next value */
        if (d == TS_ERR) error(E_FREAD, fn_frq); else break; }
      if (buf[0] == '\0') {     /* if name read is empty */
        if (d != TS_REC) error(E_EXPVAL, fn_frq, k+1);
        continue;               /* check for a missing name */
      }                         /* and skip empty lines */
      if (d != TS_FLD) error(E_EXPNUM, fn_frq, k+1);
      i = att_valid(att, buf);  /* get the value identifier */
      if (i < 0) {              /* and check it */
        io_error(E_VALUE, fn_frq, k+1, buf, 1); error(1); }
      d = ts_next(as_tabscan(attset), in, buf, AS_MAXLEN);
      if (d == TS_ERR) error(E_FREAD, fn_frq);
      if (d != TS_REC) {        /* check the number of fields */
        io_error(E_FLDCNT, fn_frq, k+1, "", 3, 2); error(1); }
      freqs[i] = strtod(buf, &s);    /* read the value frequency */
      if ((s == buf) || *s || (freqs[i] < 0)) {
        io_error(E_NUMBER, fn_frq, k+1, buf, 2); error(1); }
    }                           /* convert frequency to a number */
    if (in != stdin) fclose(in);/* close the input file */
    in = NULL;                  /* and clear the variable */
    fprintf(stderr, "done.\n"); /* print a success message */
  }
  tab_reduce(table);            /* reduce and balance the table */
  tab_balance(table, clsid, wgtsum, freqs);

  /* --- write output table --- */
  if (io_tabout(table, fn_out, outflags, 1) != 0)
    error(1);                   /* write the balanced table */

  /* --- clean up --- */
  #ifndef NDEBUG
  if (freqs) free(freqs);       /* delete frequency vector, */
  tab_delete(table, 1);         /* table, and attribute set */
  #endif
  #ifdef STORAGE
  showmem("at end of program"); /* check memory usage */
  #endif
  return 0;                     /* return 'ok' */
}  /* main() */