text: #include <stdio.h>
  #include <string.h>
  #include <stdlib.h>
  #include <ctype.h>
  #include <errno.h>
  
  #include "mex.h"
  
  #ifdef MX_API_VER
  #if MX_API_VER < 0x07030000
  typedef int mwIndex;
  #endif 
  #endif 
  #ifndef max
  #define max(x,y) (((x)>(y))?(x):(y))
  #endif
  #ifndef min
  #define min(x,y) (((x)<(y))?(x):(y))
  #endif
  
  void exit_with_help()
  {
  	mexPrintf(
  	"Usage: [label_vector, instance_matrix] = libsvmread('filename');\n"
  	);
  }
  
  static void fake_answer(int nlhs, mxArray *plhs[])
  {
  	int i;
  	for(i=0;i<nlhs;i++)
  		plhs[i] = mxCreateDoubleMatrix(0, 0, mxREAL);
  }
  
  static char *line;
  static int max_line_len;
  
  static char* readline(FILE *input)
  {
  	int len;
  	
  	if(fgets(line,max_line_len,input) == NULL)
  		return NULL;
  
  	while(strrchr(line,'\n') == NULL)
  	{
  		max_line_len *= 2;
  		line = (char *) realloc(line, max_line_len);
  		len = (int) strlen(line);
  		if(fgets(line+len,max_line_len-len,input) == NULL)
  			break;
  	}
  	return line;
  }
  
  // read in a problem (in libsvm format)
  void read_problem(const char *filename, int nlhs, mxArray *plhs[])
  {
  	int max_index, min_index, inst_max_index;
  	size_t elements, k, i, l=0;
  	FILE *fp = fopen(filename,"r");
  	char *endptr;
  	mwIndex *ir, *jc;
  	double *labels, *samples;
  
  	if(fp == NULL)
  	{
  		mexPrintf("can't open input file %s\n",filename);
  		fake_answer(nlhs, plhs);
  		return;
  	}
  
  	max_line_len = 1024;
  	line = (char *) malloc(max_line_len*sizeof(char));
  
  	max_index = 0;
  	min_index = 1; // our index starts from 1
  	elements = 0;
  	while(readline(fp) != NULL)
  	{
  		char *idx, *val;
  		// features
  		int index = 0;
  
  		inst_max_index = -1; // strtol gives 0 if wrong format, and precomputed kernel has <index> start from 0
  		strtok(line," \t"); // label
  		while (1)
  		{
  			idx = strtok(NULL,":"); // index:value
  			val = strtok(NULL," \t");
  			if(val == NULL)
  				break;
  
  			errno = 0;
  			index = (int) strtol(idx,&endptr,10);
  			if(endptr == idx || errno != 0 || *endptr != '\0' || index <= inst_max_index)
  			{
  				mexPrintf("Wrong input format at line %d\n",l+1);
  				fake_answer(nlhs, plhs);
  				return;
  			}
  			else
  				inst_max_index = index;
  
  			min_index = min(min_index, index);
  			elements++;
  		}
  		max_index = max(max_index, inst_max_index);
  		l++;
  	}
  	rewind(fp);
  
  	// y
  	plhs[0] = mxCreateDoubleMatrix(l, 1, mxREAL);
  	// x^T
  	if (min_index <= 0)
  		plhs[1] = mxCreateSparse(max_index-min_index+1, l, elements, mxREAL);
  	else
  		plhs[1] = mxCreateSparse(max_index, l, elements, mxREAL);
  
  	labels = mxGetPr(plhs[0]);
  	samples = mxGetPr(plhs[1]);
  	ir = mxGetIr(plhs[1]);
  	jc = mxGetJc(plhs[1]);
  
  	k=0;
  	for(i=0;i<l;i++)
  	{
  		char *idx, *val, *label;
  		jc[i] = k;
  
  		readline(fp);
  
  		label = strtok(line," \t\n");
  		if(label == NULL)
  		{
  			mexPrintf("Empty line at line %d\n",i+1);
  			fake_answer(nlhs, plhs);
  			return;
  		}
  		labels[i] = strtod(label,&endptr);
  		if(endptr == label || *endptr != '\0')
  		{
  			mexPrintf("Wrong input format at line %d\n",i+1);
  			fake_answer(nlhs, plhs);
  			return;
  		}
  
  		// features
  		while(1)
  		{
  			idx = strtok(NULL,":");
  			val = strtok(NULL," \t");
  			if(val == NULL)
  				break;
  
  			ir[k] = (mwIndex) (strtol(idx,&endptr,10) - min_index); // precomputed kernel has <index> start from 0
  
  			errno = 0;
  			samples[k] = strtod(val,&endptr);
  			if (endptr == val || errno != 0 || (*endptr != '\0' && !isspace(*endptr)))
  			{
  				mexPrintf("Wrong input format at line %d\n",i+1);
  				fake_answer(nlhs, plhs);
  				return;
  			}
  			++k;
  		}
  	}
  	jc[l] = k;
  
  	fclose(fp);
  	free(line);
  
  	{
  		mxArray *rhs[1], *lhs[1];
  		rhs[0] = plhs[1];
  		if(mexCallMATLAB(1, lhs, 1, rhs, "transpose"))
  		{
  			mexPrintf("Error: cannot transpose problem\n");
  			fake_answer(nlhs, plhs);
  			return;
  		}
  		plhs[1] = lhs[0];
  	}
  }
  
  void mexFunction( int nlhs, mxArray *plhs[],
  		int nrhs, const mxArray *prhs[] )
  {
  	char filename[256];
  
  	if(nrhs != 1 || nlhs != 2)
  	{
  		exit_with_help();
  		fake_answer(nlhs, plhs);
  		return;
  	}
  
  	mxGetString(prhs[0], filename, mxGetN(prhs[0]) + 1);
  
  	if(filename == NULL)
  	{
  		mexPrintf("Error: filename is NULL\n");
  		return;
  	}
  
  	read_problem(filename, nlhs, plhs);
  
  	return;
  }
  
  