/**
 *  match_breakpoints_files
 *  Check the Tracer#breakpoints_cache if any breakpoints match the given
 *  tracepoint_path. Return 1 if found. Otherwise 0;
 */
static int
match_breakpoints_files(VALUE self, VALUE tracepoint_path)
{
    int i;
    char *c_tracepoint_path;
    VALUE path_breakpoints_hash;
    VALUE breakpoints_paths;
    VALUE *c_breakpoints_paths;
    int breakpoints_paths_len;

    // Return 0 if the given path is Qnil
    if(!RTEST(tracepoint_path)) {
        return 0;
    }

    c_tracepoint_path = rb_string_value_cstr(&tracepoint_path);
    path_breakpoints_hash = rb_iv_get(self, "@breakpoints_cache");
    breakpoints_paths = hash_get_keys(path_breakpoints_hash);
    c_breakpoints_paths = RARRAY_PTR(breakpoints_paths);
    breakpoints_paths_len = RARRAY_LEN(breakpoints_paths);

    for (i = 0; i < breakpoints_paths_len; i++) {
        VALUE breakpoint_path = c_breakpoints_paths[i];
        char *c_breakpoint_path = rb_string_value_cstr(&breakpoint_path);

        if (strcmp(c_tracepoint_path, c_breakpoint_path) == 0) {
            return 1;
        }
    }

    return 0;
}
Beispiel #2
0
VALUE MHLookNFeelBindings::GetTextWidth(VALUE rSelf, VALUE rFont, VALUE rText) {
    MHLookNFeel *cSelf = Get()->getPointer(rSelf);
    std::string cFont = rb_string_value_cstr(&rFont);
    std::string cText = rb_string_value_cstr(&rText);

    int width = cSelf->getTextWidth(cFont, cText);
    return INT2NUM(width);
}
Beispiel #3
0
VALUE MHLookNFeelBindings::CreateTextRenderable(VALUE rSelf, VALUE rFont, VALUE rColor, VALUE rText) {
    MHLookNFeel *cSelf = Get()->getPointer(rSelf);

    std::string cText = rb_string_value_cstr(&rText);
    std::string cFont = rb_string_value_cstr(&rFont);

    Color4 cColor;
    for(int i=0; i < RARRAY_LEN(rColor) && i < 4; i++) {
        cColor[i] = NUM2DBL(rb_ary_entry(rColor, i));
    }

    Renderable *cRenderable = cSelf->createTextRenderable(cFont, cColor, cText);
    return NEW_RUBY_OBJECT(RenderableBindings, cRenderable);
}
Beispiel #4
0
VALUE MHLookNFeelBindings::SplitTextAt(VALUE rSelf, VALUE rFont, VALUE rText, VALUE rWidth) {
    MHLookNFeel *cSelf = Get()->getPointer(rSelf);
    std::string cFont = rb_string_value_cstr(&rFont);
    std::string cText = rb_string_value_cstr(&rText);

    std::vector<std::string> snippets;
    cSelf->splitTextAt(cFont, cText, NUM2INT(rWidth), snippets);

    std::vector<std::string>::iterator itr = snippets.begin();
    VALUE rSnippets = rb_ary_new();
    for(; itr != snippets.end(); itr++) {
        rb_ary_push(rSnippets, rb_str_new2((*itr).c_str()));
    }
    return rSnippets;
}
/*
 * convert a ruby hash to TDigipassBlob structure
 */
static void rbhash_to_digipass(VALUE data, TDigipassBlob* dpdata) {
  memset(dpdata, 0, sizeof(dpdata));

  VALUE blob = rb_hash_aref(data, rb_str_new2("blob"));
  VALUE serial = rb_hash_aref(data, rb_str_new2("serial"));
  VALUE app_name = rb_hash_aref(data, rb_str_new2("app_name"));
  VALUE flag1 = rb_hash_aref(data, rb_str_new2("flags1"));
  VALUE flag2 = rb_hash_aref(data, rb_str_new2("flags2"));

  strcpy(dpdata->Blob, rb_string_value_cstr(&blob));
  strncpy(dpdata->Serial, rb_string_value_cstr(&serial), sizeof(dpdata->Serial)); 
  strncpy(dpdata->AppName, rb_string_value_cstr(&app_name), sizeof(dpdata->AppName));
  dpdata->DPFlags[0] = rb_fix2int(flag1);
  dpdata->DPFlags[1] = rb_fix2int(flag2);
}
/*
 * do import a dpx file containing
 */
static VALUE vacman_import(VALUE module, VALUE filename, VALUE key) {
  TDPXHandle dpx_handle;
  aat_int16 appl_count;
  aat_ascii appl_names[13*8];
  aat_int16 token_count;

  aat_int32 result = AAL2DPXInit(&dpx_handle, rb_string_value_cstr(&filename), rb_string_value_cstr(&key), 
                                 &appl_count, &appl_names, &token_count);

  if (result != 0) {
  	raise_error("AAL2DPXInit", result);
    return;
  }
    
  aat_ascii sw_out_serial_No[22+1];
  aat_ascii sw_out_type[5+1];
  aat_ascii sw_out_authmode[2+1];
  TDigipassBlob dpdata;

	VALUE list = rb_ary_new();  

  while (1) {
	  result = AAL2DPXGetToken(&dpx_handle,
	            &KernelParms,
	            appl_names,
	            sw_out_serial_No,
	            sw_out_type,
	            sw_out_authmode,
	            &dpdata);


	  if (result < 0) {
	  	raise_error("AAL2DPXGetToken", result);
	    return;
	  }
		if (result == 107) break;

	  VALUE hash = rb_hash_new();
	  
    digipass_to_rbhash(&dpdata, hash);
   
	  rb_ary_push(list, hash);  	
  }

  AAL2DPXClose(&dpx_handle);

  return list;
}
Beispiel #7
0
/* call-seq:
 *   window.setTitle( new_title )
 *
 * Change the title of the window. 
 */
static VALUE Window_SetTitle( VALUE self, VALUE aTitle )
{
	sf::Window *object = NULL;
	Data_Get_Struct( self, sf::Window, object );
	object->SetTitle( rb_string_value_cstr( &aTitle ) );
	return Qnil;
}
Beispiel #8
0
static VALUE application_initialize(VALUE self, VALUE args) {
    if (rb_thread_main() != rb_thread_current()) {
        rb_raise(rb_eThreadError, "Initializing QML::Application outside the main thread");
    }

    application_t *data;
    TypedData_Get_Struct(self, application_t, &data_type, data);

    if (rb_type(args) != T_ARRAY) {
        rb_raise(rb_eTypeError, "Expected Array");
    }

    args = rb_ary_concat(rb_ary_new_from_args(1, rb_argv0), args);

    int argc = RARRAY_LEN(args);
    char **argv = malloc(argc * sizeof(char *));

    for (int i = 0; i < argc; ++i) {
        VALUE arg = RARRAY_AREF(args, i);
        argv[i] = rb_string_value_cstr(&arg);
    }

    data->application = qmlbind_application_new(argc, argv);

    return self;
}
Beispiel #9
0
VALUE MHLookNFeelBindings::CreateRectRenderable(VALUE rSelf, VALUE rW, VALUE rH, VALUE rMatName) {
    MHLookNFeel *cSelf = Get()->getPointer(rSelf);
    std::string cMatName = rb_string_value_cstr(&rMatName);

    Renderable *cRenderable = cSelf->createRectRenderable(NUM2INT(rW), NUM2INT(rH), 0, 0, cMatName);
    return NEW_RUBY_OBJECT(RenderableBindings, cRenderable);
}
Beispiel #10
0
static VALUE engine_evaluate(VALUE self, VALUE str, VALUE file, VALUE lineNum) {
    qmlbind_engine engine = rbqml_get_engine(self);

    evaluate_data data;
    data.engine = engine;
    data.str = rb_string_value_cstr(&str);
    data.file = rb_string_value_cstr(&file);
    data.lineNum = NUM2INT(lineNum);

    qmlbind_value value = rb_thread_call_without_gvl(&evaluate_impl, &data, RUBY_UBF_IO, NULL);

    VALUE result = rbqml_to_ruby(value);
    qmlbind_value_release(value);

    return result;
}
Beispiel #11
0
// takes a string and returns a downcased version where capitals are now separated by underscores
static VALUE underscore(VALUE self, VALUE str)
{
  if (TYPE(str) == T_NIL) return Qnil;

  char *str_value = rb_string_value_cstr(&str);
  char orig_str[strlen(str_value) + 1];

  filter(orig_str, str_value);
  preprocess(orig_str);

  // manually null-terminating the string because on Fedora for strings of length 16 this breaks otherwise
  orig_str[strlen(str_value)] = '\0';

  char new_str[strlen(orig_str) * 2];
  char prev;
  int orig_idx, new_idx;

  for (orig_idx = 0, new_idx = 0; orig_str[orig_idx] != '\0'; orig_idx++) {
    if (orig_idx != 0 && isupper(orig_str[orig_idx])) {
      new_str[new_idx++] = '_';
    }
    new_str[new_idx++] = tolower(orig_str[orig_idx]);
    prev = tolower(orig_str[orig_idx]);
  }

  return rb_str_new(new_str, new_idx);
}
static void decode_lat_lon(VALUE vlat, VALUE vlon, GeographicLib::Math::real &lat, GeographicLib::Math::real &lon)
{
  std::string slat, slon;
  if (rb_type(vlat) == T_STRING && rb_type(vlon) == T_STRING) {
    slat = rb_string_value_cstr(&vlat);
    slon = rb_string_value_cstr(&vlon);
    try {
      GeographicLib::DMS::DecodeLatLon(slat, slon, lat, lon);
    } catch (GeographicLib::GeographicErr e) {
      rb_raise(rb_eRuntimeError, "This is not a valid position.");
    }
  } else {
    lat = rb_num2dbl(vlat);
    lon = rb_num2dbl(vlon);
  }
}
Beispiel #13
0
VALUE MHLookNFeelBindings::GetTextHeight(VALUE rSelf, VALUE rFont) {
    MHLookNFeel *cSelf = Get()->getPointer(rSelf);
    std::string cFont = rb_string_value_cstr(&rFont);

    int height = cSelf->getTextHeight(cFont);
    return INT2NUM(height);
}
Beispiel #14
0
VALUE MHWorldBindings::Save(VALUE rSelf, VALUE world) {
    MHWorld *cSelf = MHWorldBindings::Get()->getPointer(rSelf);
    std::string cWorld = rb_string_value_cstr(&world);

    cSelf->save(cWorld);

    return rSelf;
}
Beispiel #15
0
VALUE MHWorldBindings::Load(VALUE rSelf, VALUE world) {
    MHWorld *cSelf = MHWorldBindings::Get()->getPointer(rSelf);
    std::string cWorld = rb_string_value_cstr(&world);
    cSelf->load(cWorld);
    NEW_RUBY_OBJECT(LiquidManagerBindings, cSelf->getLiquidManager());
    NEW_RUBY_OBJECT(TerrainBindings, cSelf->getTerrain());
    return rSelf;
}
Beispiel #16
0
/* call-seq:
 *   window.create( mode, title, style = SFML::Style::Default, settings = SFML::ContextSettings.new )
 *
 * Create (or recreate) the window. 
 *
 * If the window was already created, it closes it first. If style contains Style::Fullscreen, 
 * then mode must be a valid video mode.
 */
static VALUE Window_Create( int argc, VALUE *args, VALUE self )
{
	sf::Window *object = NULL;
	sf::VideoMode *mode = NULL;
	sf::ContextSettings *settings = NULL;
	VALUE arg0 = Qnil;
	
	Data_Get_Struct( self, sf::Window, object );
	switch( argc )
	{
		case 2:
			arg0 = VideoMode_ForceType( args[0] );
			VALIDATE_CLASS( arg0, globalVideoModeClass, "first" );
			VALIDATE_CLASS( args[1], rb_cString, "second" );
			Data_Get_Struct( arg0, sf::VideoMode, mode );
			object->Create( *mode ,rb_string_value_cstr( &args[1] ) );
			break;
		case 3:
			arg0 = VideoMode_ForceType( args[0] );
			VALIDATE_CLASS( arg0, globalVideoModeClass, "first" );
			VALIDATE_CLASS( args[1], rb_cString, "second" );
			VALIDATE_CLASS( args[2], rb_cFixnum, "third" );
			Data_Get_Struct( arg0, sf::VideoMode, mode );
			object->Create( *mode, rb_string_value_cstr( &args[1] ), FIX2INT( args[2] ) );
			break;
		case 4:
			arg0 = VideoMode_ForceType( args[0] );
			VALIDATE_CLASS( arg0, globalVideoModeClass, "first" );
			VALIDATE_CLASS( args[1], rb_cString, "second" );
			VALIDATE_CLASS( args[2], rb_cFixnum, "third" );
			VALIDATE_CLASS( args[3], globalContextSettingsClass, "fourth" );
			Data_Get_Struct( arg0, sf::VideoMode, mode );
			Data_Get_Struct( args[3], sf::ContextSettings, settings );
			object->Create( *mode, rb_string_value_cstr( &args[1] ), FIX2INT( args[2] ), *settings );
			break;
		default:
			rb_raise( rb_eArgError, "Expected 2..4 arguments but was given %d", argc );
			break;
	}
	return Qnil;
}
/*
 * set kernel parameters
 */
static void vacman_set_kernal_param(VALUE module, VALUE paramname, VALUE rbval) {
  char* name = rb_string_value_cstr(&paramname);
  int val = rb_fix2int(rbval);
  if (strcmp(name, "itimewindow") == 0)
    return KernelParms.ITimeWindow = val;
  else {
    char buffer[256];
    sprintf(buffer, "invalid kernal param %s", name);
    rb_raise(e_vacmanerror, buffer);
    return;
  }
}
Beispiel #18
0
static VALUE socket_connect (VALUE self_, VALUE addr_)
{
    assert (DATA_PTR (self_));

    int rc = zmq_connect (DATA_PTR (self_), rb_string_value_cstr (&addr_));
    if (rc != 0) {
        rb_raise (rb_eRuntimeError, zmq_strerror (errno));
        return Qnil;
    }

    return Qnil;
}
Beispiel #19
0
/* call-seq:
 *   music.openFromFile()	-> true or false
 *
 * Open a music from an audio file.
 *
 * This function doesn't start playing the music (call Play() to do so). Here is a complete list of all the supported 
 * audio formats: ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam, w64, mat4, mat5 pvf, htk, sds, avr, sd2,
 * caf, wve, mpc2k, rf64.
 */
static VALUE Music_OpenFromFile( VALUE self, VALUE aFilename )
{
	sf::Music *object = NULL;
	Data_Get_Struct( self, sf::Music, object );
	if( object->OpenFromFile( rb_string_value_cstr( &aFilename ) ) == true )
	{
		return Qtrue;
	}
	else
	{
		return Qfalse;
	}
}
Beispiel #20
0
VALUE 
method_init_player(VALUE self) {
	VALUE tick_wav, tock_wav;
	char *tick_wav_str, *tock_wav_str;

	alutInit (NULL, NULL);

	tick_wav = rb_const_get(lolrbmet_class, rb_intern("TickFile"));
	tick_wav_str = rb_string_value_cstr(&tick_wav);

	tock_wav = rb_const_get(lolrbmet_class, rb_intern("TockFile"));
	tock_wav_str = rb_string_value_cstr(&tock_wav);

	tickBuffer = alutCreateBufferFromFile (tick_wav_str);
	tockBuffer = alutCreateBufferFromFile (tock_wav_str);

	alGenSources (1, &tickSource);
	alGenSources (1, &tockSource);

	alSourcei (tickSource, AL_BUFFER, tickBuffer);
	alSourcei (tockSource, AL_BUFFER, tockBuffer);
}
static void decode_azi(VALUE vazi, GeographicLib::Math::real &azi)
{
  std::string sazi;
  if (rb_type(vazi) == T_STRING) {
    sazi = rb_string_value_cstr(&vazi);
    try {
      azi = GeographicLib::DMS::DecodeAzimuth(sazi);
    } catch (GeographicLib::GeographicErr e) {
      rb_raise(rb_eRuntimeError, "This is not a valid azimuth.");
    }
  } else {
    azi = rb_num2dbl(vazi);
  }
}
/*
 * verify password 
 * this is the main usecase, check the use input for authentication
 */
static VALUE vacman_verify_password(VALUE module, VALUE data, VALUE password ) {
  int result;
  TDigipassBlob dpdata;
  
  rbhash_to_digipass(data, &dpdata);  

  char buffer[256];
  result = AAL2VerifyPassword(&dpdata, &KernelParms, rb_string_value_cstr(&password), 0);
  
  digipass_to_rbhash(&dpdata, data);

  if (result == 0)
    return Qtrue;
  else
    raise_error("AAL2VerifyPassword", result);
}
/**
 *  line_trace_callback
 *  Callback function for thread line event tracing. It checks Tracer#breakpoints_cache
 *  for any breakpoints trigger on current line called. Then trigger evaluation
 *  procedure if found matching breakpoints. It also skip breakpoints that are
 *  already marked completed.
 */
static void
line_trace_callback(rb_event_flag_t event, VALUE data, VALUE obj, ID mid, VALUE klass)
{
    VALUE self = data;
    VALUE trace_path;
    int c_trace_lineno;
    const char *c_trace_path;
    VALUE trace_binding;
    VALUE call_stack_bindings;
    ID callers_id;
    ID breakpoints_hit_id;
    VALUE matching_result;

    c_trace_path = rb_sourcefile();
    // Ensure C_trace_path is absolute path
    trace_path = rb_str_new_cstr(c_trace_path);
    trace_path = rb_file_expand_path(trace_path, Qnil);

    if(!RTEST(trace_path)) {
        return;
    }

    c_trace_path = rb_string_value_cstr(&trace_path);

    c_trace_lineno = rb_sourceline();
    matching_result = match_breakpoints(self, c_trace_path, c_trace_lineno);

    CONST_ID(callers_id, "callers");
    CONST_ID(breakpoints_hit_id, "breakpoints_hit");

    // If matching result isn't an array, it means we're in completely wrong file,
    // or not on the right line. Turn line tracing off if we're in wrong file.
    if (!RB_TYPE_P(matching_result, T_ARRAY)) {
        if (!RTEST(matching_result)) {
            disable_line_trace_for_thread(Qnil);
        }
        return;
    }

    trace_binding = rb_binding_new();
    call_stack_bindings = rb_funcall(trace_binding, callers_id, 0);

    rb_funcall(self, breakpoints_hit_id, 2, matching_result, call_stack_bindings);

    return;
}
Beispiel #24
0
VALUE MHWorldBindings::CreateCamera(int argc, VALUE *argv, VALUE rSelf) {
    ASSERT(argc >= 2);

    VALUE rCameraName = argv[0];
    VALUE klass = argv[1];

    // Replace the class argument with the world reference for the default Camera c'tor.
    argv[1] = rSelf;

    MHWorld *cSelf = MHWorldBindings::Get()->getPointer(rSelf);
    std::string cCameraName = rb_string_value_cstr(&rCameraName);
    MHCamera *cam = cSelf->createCamera(cCameraName);

    VALUE rCam = NEW_RUBY_OBJECT_FULL(MHCameraBindings, cam, klass);
    rb_obj_call_init(rCam, argc, argv);

    return rCam;
}
static VALUE geographiclib_dms_decode(VALUE self, VALUE str)
{
  std::string s = rb_string_value_cstr(&str);
  try {
    GeographicLib::DMS::flag f;
    GeographicLib::Math::real angle = GeographicLib::DMS::Decode(s, f);
    VALUE r = rb_ary_new();
    rb_ary_push(r, rb_float_new(angle));
    switch (f) {
      case GeographicLib::DMS::LATITUDE: rb_ary_push(r, rb_symbol("lat")); break;
      case GeographicLib::DMS::LONGITUDE: rb_ary_push(r, rb_symbol("lon")); break;
      case GeographicLib::DMS::AZIMUTH: rb_ary_push(r, rb_symbol("azi")); break;
      case GeographicLib::DMS::NUMBER: rb_ary_push(r, rb_symbol("number")); break;
      default: rb_ary_push(r, rb_symbol("none")); break;
    }
    return r;
  } catch (GeographicLib::GeographicErr e) {
    rb_raise(rb_eRuntimeError, "String is malformed.");
  }
}
/**
 *  match_breakpoints
 *  Check the Tracer#breakpoints_cache for any matching breakpoints of given
 *  file path and line number.
 *
 *  Return a Ruby array of breakpoints found. Qtrue if no match found, but this
 *  file contains at least one breakpoint. Qnil if event triggered in a file
 *  that doesn't contain any breakpoints.
 */
static VALUE
match_breakpoints(VALUE self, const char *c_trace_path, int c_trace_lineno)
{
    int i, j;
    VALUE path_breakpoints_hash = rb_iv_get(self, "@breakpoints_cache");
    VALUE breakpoints_paths = hash_get_keys(path_breakpoints_hash);
    VALUE *c_breakpoints_paths = RARRAY_PTR(breakpoints_paths);
    int breakpoints_paths_len = RARRAY_LEN(breakpoints_paths);
    VALUE path_match = Qnil;

    // Check the file paths of @breakpoints_cache
    for (i = 0; i < breakpoints_paths_len; i++) {
        VALUE breakpoint_path = c_breakpoints_paths[i];
        char *c_breakpoint_path = rb_string_value_cstr(&breakpoint_path);

        // Found matching file path, keep going and check for the line numbers
        if (strcmp(c_trace_path, c_breakpoint_path) == 0) {
            VALUE line_breakpoint_hash = rb_hash_aref(path_breakpoints_hash, breakpoint_path);
            VALUE breakpoints_lines = hash_get_keys(line_breakpoint_hash);
            VALUE *c_breakpoints_lines = RARRAY_PTR(breakpoints_lines);
            int breakpoints_lines_len = RARRAY_LEN(breakpoints_lines);
            path_match = Qtrue;

            // Found matching breakpoints. Return the cached breakpoints array
            for (j = 0; j < breakpoints_lines_len; j++) {
                VALUE breakpoint_lineno = c_breakpoints_lines[j];
                int c_breakpoint_lineno = NUM2INT(breakpoint_lineno);

                if (c_trace_lineno == c_breakpoint_lineno) {
                    return rb_hash_aref(line_breakpoint_hash, breakpoint_lineno);
                }
            }
        }
    }

    return path_match;
}
Beispiel #27
0
/*
 * Adds a QML import path to the {Engine}.
 * @param path [String]
 * @see http://doc.qt.io/qt-5/qtqml-syntax-imports.html#qml-import-path
 */
static VALUE engine_add_import_path(VALUE self, VALUE path) {
    qmlbind_engine engine = rbqml_get_engine(self);
    path = rb_funcall(path, rb_intern("to_s"), 0);
    qmlbind_engine_add_import_path(engine, rb_string_value_cstr(&path));
    return self;
}
Beispiel #28
0
VALUE Kcsv_read(const char * filename, int instruction)
{
#else
int main(int argc, char ** argv)
{
  const char * filename = "testdatafiles/sigh2.csv";
  if (argc > 1) filename = argv[1];

  int instruction = EXTRACT_HEADER;
  // int instruction = EXTRACT_DATA;
#endif

  clock_t start;
  start = clock();
  
  char acceptable_delimiters[100] = ",|\t;";
  
  char delimiter = 0;
  int header_line_number = -1;
  
  int i;
  
  struct sNotices notices = { 0, NULL };
  struct sNotices errors = { 0, NULL };
  
  FILE * fp = fopen(filename, "rb");
  
  if (fp == NULL) { add_notice(&errors, "Could not open file"); fprintf(stderr, "Could not open file\n"); return Qnil; } // Qnil is 0 if NO_RUBY
  
  int c1 = fgetc(fp);
  int c2 = fgetc(fp);
  
  int encoding = UTF_8;
  
  if ((c1 == 0xFE && c2 == 0xFF))
  {
    add_notice(&notices, "UTF-16 small endian byte order mark encountered");
    encoding = UTF_16_BIG;
  }
  else if ((c1 == 0xFF && c2 == 0xFE))
  {
    add_notice(&notices, "UTF-16 small endian byte order mark encountered");
    encoding = UTF_16_SMALL;
  }
  else
    rewind(fp);
  
  int length = 0;
  char * line = NULL;
  
  struct tRowStat {
    int line_number;
    int num_fields;
    int num_null_fields;
    int total_alpha;
    int total_numeric;
    int total_characters;
    int delimiter;
  };
  
  struct tRowStat * row_stats = NULL;
  int num_row_stats = 0;
  
  int header_has_trailing_delimiter = 0;
  int num_lines_total = 0, num_blank_lines = 0, num_comment_lines = 0, num_content_rows = 0, number_of_incorrect_number_of_fields = 0;
  while (!feof(fp))
  {
    line = csv_get_line(fp, &length, encoding);
    
    num_lines_total++;
    if (line == NULL || length == 0 || line[0] == 0 || line[0] == 0x0A || line[0] == 0x0D) { num_blank_lines++; free(line); continue; }
    
    // need some row_stats before knowing where the header is and where the content begins
    if (num_row_stats < ROWS_TO_EVALUATE_FOR_HEADER_SEARCH)
    {
      num_row_stats++;
      row_stats = realloc(row_stats, sizeof(struct tRowStat)*num_row_stats);
      struct tRowStat * row_stat = &row_stats[num_row_stats-1];
      
      row_stat->line_number = num_lines_total - 1;
      
      struct sCounts delimiter_counts = { 0, NULL, NULL };
      get_character_distribution(&delimiter_counts, line, acceptable_delimiters);
      row_stat->delimiter = get_peak_character(&delimiter_counts);
      //if (delimiter_counts.num_characters == 0) add_notice(&notices, "Encountered a row with no valid delimiters: '%s'", line);
      free_character_distribution(&delimiter_counts);
      
      struct sRow header_row = { 0, NULL };
      get_row(&header_row, line, row_stat->delimiter, 0);
      
      row_stat->num_fields = header_row.num_fields;
      
      row_stat->num_null_fields = 0;
      for (i = 0 ; i < header_row.num_fields ; i++)
        if (header_row.fields[i] == NULL || strlen(header_row.fields[i]) == 0)
          row_stat->num_null_fields++;
      
      int is_comment = 0;
      for (i = 0 ; i < header_row.num_fields ; i++)
      {
        if (header_row.fields[i] != NULL)
        {
          unsigned int j;
          for (j = 0 ; j < strlen(header_row.fields[i]) ; j++)
          {
            if (header_row.fields[i][j] == ' ') continue;
            else if (header_row.fields[i][j] == '#') { is_comment = 1; break; }
          }
          if (is_comment == 1) break;
        }
      }
      
      if (is_comment == 1 && header_row.num_fields == 1)
      {
        num_comment_lines++;
        free_row(&header_row);
        free(line);
        continue;
      }
      free_row(&header_row);
      
      row_stat->total_alpha = 0;
      row_stat->total_characters = 0;
      struct sCounts counts = { 0, NULL, NULL };
      get_character_distribution(&counts, line, NULL);
      for (i = 0 ; i < counts.num_characters ; i++)
      {
        if ((counts.characters[i] >= 'A' && counts.characters[i] <= 'Z') || (counts.characters[i] >= 'a' && counts.characters[i] <= 'z'))
          row_stat->total_alpha += counts.charcounts[i];
        
        if ((counts.characters[i] >= '0' && counts.characters[i] <= '9') || counts.characters[i] == '$')
          row_stat->total_numeric += counts.charcounts[i];
      }
      
      for (i = 0 ; i < counts.num_characters ; i++)
        if (counts.characters[i] != row_stat->delimiter && counts.characters[i] != '"')
          row_stat->total_characters += counts.charcounts[i];
      
      free_character_distribution(&counts);
      break;
    }
    free(line);
  }
  
  int min_num_null_fields = 100000;
  int max_num_fields = 0;
  
  // update header_line_number to the first line with the maximum number of fields and minimum number of null fields
  int k;
  for (k = 0 ; k < num_row_stats ; k++)
  {
    #ifdef HEADER_SEARCH_DEBUG
    char temp[2] = { row_stats[k].delimiter, 0 };
    fprintf(stderr, "row_stats[%d].line_number = %3d   .num_null_fields = %2d   .num_fields = %2d  .delimiter = %s\n", k, row_stats[k].line_number, row_stats[k].num_null_fields, row_stats[k].num_fields, temp);
    #endif
    if (row_stats[k].num_null_fields < min_num_null_fields) min_num_null_fields = row_stats[k].num_null_fields;
    if (row_stats[k].num_fields > max_num_fields) max_num_fields = row_stats[k].num_fields;
  }
  
  for (k = 0 ; k < num_row_stats ; k++)
  {
    if (row_stats[k].num_null_fields == min_num_null_fields && row_stats[k].num_fields == max_num_fields)
    {
      header_line_number = row_stats[k].line_number;
      break;
    }
  }
  
  if (header_line_number == -1)
  for (k = 0 ; k < num_row_stats ; k++)
  {
    if (row_stats[k].num_null_fields == min_num_null_fields && row_stats[k].num_fields == max_num_fields)
    {
      header_line_number = row_stats[k].line_number;
      break;
    }
  }
  
  #ifdef HEADER_SEARCH_DEBUG
  fprintf(stderr, "header_line_number = %d\n", header_line_number);
  fprintf(stderr, "max_num_fields = %d\n", max_num_fields);
  fprintf(stderr, "min_num_null_fields = %d\n", min_num_null_fields);
  //fprintf(stderr, "min_num_null_fields = %d\n", min_num_null_fields);
  #endif
  
  rewind(fp);
  
  for (k = 0 ; k < header_line_number ; k++)
  {
    line = csv_get_line(fp, &length, encoding);
    free(line);
  }
  
  line = csv_get_line(fp, &length, encoding);
  
  struct sRow header_row = { 0, NULL };
  get_row(&header_row, line, row_stats[header_line_number].delimiter, 0);
  
  add_notice((header_row.num_fields == 0) ? &errors : &notices, "Header has %d fields", header_row.num_fields);
  
  free(line);
  
  if (instruction == EXTRACT_HEADER)
  {
    if (header_line_number == -1) return Qnil;
  
    #ifndef NO_RUBY
    VALUE header_row_rb = rb_ary_new();
    #endif
    
    int j;
    for (j = 0 ; j < header_row.num_fields ; j++)
    {
      #ifndef NO_RUBY
      if (header_row.fields[j] == NULL)
        rb_ary_push(header_row_rb, ENCODED_STR_NEW2("", "UTF-8"));
      else
        rb_ary_push(header_row_rb, ENCODED_STR_NEW2(header_row.fields[j], "UTF-8"));
      #else
      printf("%s%s", header_row.fields[j], (j == header_row.num_fields - 1) ? "\n" : "|");
      #endif
    }
    
    #ifndef NO_RUBY
    return header_row_rb;
    #else
    return 0;
    #endif
  }
  else if (instruction == EXTRACT_DATA)
  {
    while (!feof(fp))
    {
      line = csv_get_line(fp, &length, encoding);
      
      if (line == NULL || length == 0 || line[0] == 0 || line[0] == 0x0A || line[0] == 0x0D) { num_blank_lines++; free(line); continue; }
      
      num_content_rows++;
      struct sRow row = { 0, NULL };
      get_row(&row, line, row_stats[0].delimiter, 0);
      
      #ifndef NO_RUBY
      if (instruction == EXTRACT_DATA && rb_block_given_p())
      {
        int j;
        VALUE row_rb = rb_ary_new();
        for (j = 0 ; j < row.num_fields ; j++)
          if (row.fields[j] == NULL)
            rb_ary_push(row_rb, ENCODED_STR_NEW2("", "UTF-8"));
          else
            rb_ary_push(row_rb, ENCODED_STR_NEW2(row.fields[j], "UTF-8"));
        
        rb_yield(row_rb);
      }
      #else
      if (instruction == EXTRACT_DATA && num_content_rows <= 10)
      {
        fprintf(stdout, "(");
        int j;
        for (j = 0 ; j < row.num_fields ; j++)
        {
          //fprintf(stderr, "%s%s", row.fields[j], (j == row.num_fields - 1) ? "\n" : "|");
          fprintf(stdout, "\"%s\"%s", row.fields[j], (j == row.num_fields - 1) ? "" : ",");
        }
        fprintf(stdout, ")\n");
      }
      #endif
      free(line);
      free_row(&row);
    }
  }
  
  free_row(&header_row);
  
  num_row_stats = 0;
  free(row_stats);
  
  if (ferror(fp)) add_notice(&errors, "Error reading from file");
  
  if (number_of_utf8_extended_characters > 0)
    add_notice(&notices, "number_of_utf8_extended_characters = %d", number_of_utf8_extended_characters);
  
  if (header_line_number != -1) add_notice(&notices, "Header on line: %d", header_line_number);
  else add_notice(&notices, "Alpha analysis suggests no header");
  
  if (number_of_incorrect_number_of_fields > 0) add_notice(&errors, "Number of rows with an incorrect number of fields: %d", number_of_incorrect_number_of_fields);
  if (num_blank_lines > 0) add_notice(&notices, "Number of blank lines: %d", num_blank_lines);
  if (num_comment_lines > 0) add_notice(&notices, "Number of comments: %d", num_comment_lines);
  
  add_notice(&notices, "Number of content rows: %d", num_content_rows);
  add_notice(&notices, "Number of lines total: %d", num_lines_total);
  
  clock_t end;
  end = clock();
  
  add_notice(&notices, "Appoximate execution time: %f", (float)(end-start)/(float)CLOCKS_PER_SEC);
  
  #ifndef NO_RUBY
  VALUE ret = rb_hash_new();
  rb_hash_aset(ret, ENCODED_STR_NEW2("file_name", "UTF-8"), ENCODED_STR_NEW2(filename, "UTF-8"));
  
  if (errors.num_notices)
  {
    VALUE ret2 = rb_ary_new();
    for (i = 0 ; i < errors.num_notices ; i++)
      rb_ary_push(ret2, ENCODED_STR_NEW2(errors.notices[i], "UTF-8"));
    rb_hash_aset(ret, ENCODED_STR_NEW2("errors", "UTF-8"), ret2);
  }
  #else
  if (errors.num_notices > 0)
    fprintf(stderr, "ERRORS:\n");
  for (i = 0 ; i < errors.num_notices ; i++)
    fprintf(stderr, "  %d: %s\n", i, errors.notices[i]);
  #endif
  free_notices(&errors);
  
  #ifndef NO_RUBY
  if (notices.num_notices)
  {
    VALUE ret3 = rb_ary_new();
    for (i = 0 ; i < notices.num_notices ; i++)
      rb_ary_push(ret3, ENCODED_STR_NEW2(notices.notices[i], "UTF-8"));
    rb_hash_aset(ret, ENCODED_STR_NEW2("notices", "UTF-8"), ret3);
  }
  #else
  if (notices.num_notices > 0)
    fprintf(stderr, "Notices:\n");
  for (i = 0 ; i < notices.num_notices ; i++)
    fprintf(stderr, "  %d: %s\n", i, notices.notices[i]);
  int ret = 0;
  #endif
  
  free_notices(&notices);
  
  fclose(fp);
  
  return ret;
}

#ifndef NO_RUBY
VALUE method_yield_data(VALUE self, VALUE file)
{
  if (TYPE(file) != T_STRING) rb_raise(rb_eArgError, "filename is not a string, but instead of type '%d' and should be '%d' (in C)", TYPE(file), T_STRING);
  
  return Kcsv_read(rb_string_value_cstr(&file), EXTRACT_DATA);
}

VALUE method_extract_header(VALUE self, VALUE file)
{
  if (TYPE(file) != T_STRING) rb_raise(rb_eArgError, "filename is not a string, but instead of type '%d' and should be '%d' (in C)", TYPE(file), T_STRING);
  
  return Kcsv_read(rb_string_value_cstr(&file), EXTRACT_HEADER);
}

void Init_kcsv()
{
  VALUE Kcsv_module = rb_define_module("Kcsv");
  rb_define_singleton_method(Kcsv_module, "read", method_yield_data, 1);
  rb_define_singleton_method(Kcsv_module, "foreach", method_yield_data, 1);
  rb_define_singleton_method(Kcsv_module, "extract_header", method_extract_header, 1);
}
Beispiel #29
0
static VALUE component_load_data(VALUE self, VALUE data, VALUE path) {
    qmlbind_component component = rbqml_get_component(self);
    qmlbind_component_set_data(component, rb_string_value_cstr(&data), rb_string_value_cstr(&path));

    return self;
}