/*
 *                      scope_to_mat
 *                      ------------
 * Program to read files in ANALOG Scope dump format and write them
 * in Matlab .mat format. It is necessary to use .mat since matlab
 * takes forever to read any significant amount of data from .m files.
 * This program believes that the following is Analog scope dump format.
 * This was deduced from a few samples.
 * 
 * dump_name <file name given for dump> (
 * (DATA:
 * (TITLE: <variable_name> )
 * (POINTS:
 *     .
 *  <..data.. in nnexx notation>
 *     .
 * ))
 * (DATA:
 * (TITLE: <variable_name> )
 * (POINTS:
 *    .
 *    .
 * ))
 * )   matches the ( at beginning and indicates end-of-file
 *
 *
 * Note a few things:
 * 1. There is no way to determine how many data points there will be.
 * 2. The variable names have an odd surround which tends to include
 *    \. In any case, variable names in Analog can include characters that
 *    Matlab cannot handle (like -). This code strips \, but does nothing
 *    with embedded Matlab illegal characters.
 * 3. The file_name provided by Analog is written as a string variable
 *    whose name is 'scope_file'.
 * 4. The use of malloc and realloc is not wonderful. It would be fairly
 *    safe to replace them with a LARGE intial allocation, and then test
 *    for overflow.
 *
 * Author: M. D. Godfrey, Stanford, June 1991 godfrey@isl.stanford.edu
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#define MAXARRAY 2000     /* Initial malloc in real*8  */
#define COMPTYPE 1000     /* See MatLab doc. This setting is for SUN, etc. */

void main(argc,argv)
int argc;
char *argv[];
{
	FILE *fp, *fout;
	char name[200], vname[200];
	int type, mrows, ncols, imagf;
	double *xr, *xi, *xrb;
	float xx;

/*
 * Take the "b" out of the fopen on systems that do not do newline
 * translation, for example Unix and Macintosh systems.  Leave
 * the "b" in for MS-DOS and VAX/VMS C compilers.  The "rfm=var"
 * is needed for VAX/VMS C compilers to make the file type the
 * same as when MATLAB saves a .MAT file (it does this for
 * performance reasons).
 */
	
       char fname[200], fnamin[200];
       char dummy[200];
       char ch;
       char *vnam;
       int i;

	if ( argc != 2) {
	  printf("Scope_to_mat usage: scope_to_mat input_file (without .text"
		 " extension)\n"); exit(1); }
	strcpy( fname, argv[1]);
	strcpy(fnamin, fname); strcat(fnamin, ".text");
	printf("Scope_to_mat converting file: %s.", fnamin);
	fp = fopen(fnamin,"r");
	if (fp == NULL) {
	    printf("\nScope_to_mat Error: %s not found.\n", fname);
	    exit(1);
	}
	strcat(fname,".mat");
	if ((fout = fopen(fname,"wb")) == NULL)
	{
	    printf ("\nScope_to_mat Error: Cannot Open %s.\n", fname);
	    exit (1);
	}
/* Read Analog Scope dump format: */

	i = 0; fgets(dummy, 200, fp); /* Unconditionally read BLANK line. */
	xr = (double *)malloc(sizeof(double)*200);
	while ((ch = fgetc(fp)) != '.'){ /* Read file_name as set by Analog */
	  xr[i++] = (double) ch;
	}
	fgets(dummy, 200, fp); 
	type= COMPTYPE + 1; mrows = 1; imagf = 0;
	strcat(name, "scope_file");
	ncols = i; 
	savemat(fout, type, name, mrows, ncols, imagf, xr, xi);
	free(xr);
	type = COMPTYPE;
	fgets(dummy, 200, fp); printf("\n%s", dummy);

	while( strncmp(dummy, "(DATA:\0", 6) == 0){
	fscanf(fp, "%s %s", dummy, vname); printf("%s", dummy);
	xr = (double *)malloc(sizeof(double)*MAXARRAY);
	vnam = strtok(vname,"\\) ");
	printf("Reading variable: %s. ", vnam);
	fgets(dummy, 200, fp); /* read ) after title variable. */
	fgets(dummy, 200, fp); /*  skip over (POINTS: */
	printf("\n%s", dummy);
	i = 0;

	while ((ch = getc(fp)) != ')' ) {
	  ungetc(ch, fp); 
	  fgets(dummy, 200, fp); /* printf("\n%s", dummy); */
	  sscanf(dummy, "%e", &xx);
	  xr[i++] = xx;
	  if( ((i/MAXARRAY)*MAXARRAY) == i){ 
	    realloc(xr, sizeof(double)*(i + MAXARRAY ));
	  }
	}
	ncols = i;
	printf("Variable %s has %d values.\n", vnam, ncols);
 	savemat(fout, type, vnam, mrows, ncols, imagf, xr, xi);
	fgets(dummy, 200, fp); fgets(dummy, 200, fp); printf("\n%s", dummy);
	free(xr);
      }
	fclose(fp); fclose(fout);

}


