Listing 1

/* Listing-1: recls-Ruby extension entry point */

static VALUE mRecls;      /* Recls module:     ::Recls                */
static VALUE cFileSearch; /* FileSearch class: ::Recls::FileSearch     */
static VALUE cEntry;      /* Entry class:    ::Recls::FileSearch::Entry*/
 . . .
void Init_recls()
{
  char  version[101];
  TRACETODEBUGGER("Initialising recls extension for Ruby\n");
  sprintf(version, "%d.%d.%d", RECLS_VER_MAJOR, RECLS_VER_MINOR
                             , RECLS_VER_REVISION);
  /* Recls module */
  mRecls = rb_define_module("Recls");
  rb_define_const(mRecls, "RECLS_VERSION",rb_str_new2(version));
  rb_define_const(mRecls, "VERSION",rb_str_new2(version));
  rb_define_const(mRecls, "RECLS_F_FILES", rb_uint2inum(RECLS_F_FILES));
  . . . and for "RECLS_F_DIRECTORIES", "RECLS_F_LINKS", 
    "RECLS_F_DEVICES", "RECLS_F_TYPEMASK", "RECLS_F_RECURSIVE",
    "RECLS_F_NO_FOLLOW_LINKS", "RECLS_F_DIRECTORY_PARTS" and
    "RECLS_F_DETAILS_LATER"
  rb_define_module_function(mRecls, "roots", recls_roots_get, 0);
  rb_define_module_function(mRecls, "pathNameSeparator"
                                  , recls_pathNameSeparator_get, 0);
  rb_define_module_function(mRecls, "pathSeparator"
                                  , recls_pathSeparator_get, 0);
  rb_define_module_function(mRecls, "wildcardsAll"
                                  , recls_wildcardsAll_get, 0);
  /* FileSearch class */
  cFileSearch = rb_define_class_under(mRecls, "FileSearch", rb_cObject);
  rb_include_module(cFileSearch, rb_mEnumerable);
  rb_define_method(cFileSearch, "initialize", FileSearch_initialize
                                            , 3);
  rb_define_method(cFileSearch, "each", FileSearch_each, 0);
  rb_define_attr(cFileSearch,   "searchRoot", 1, 0);
  rb_define_attr(cFileSearch,   "pattern", 1, 0);
  rb_define_attr(cFileSearch,   "flags", 1, 0);

  /* Entry class */
  cEntry = rb_define_class_under(cFileSearch, "Entry", rb_cObject);
  rb_include_module(cEntry, rb_mComparable);
  rb_define_attr(cEntry,   "path", 1, 0);
  rb_define_attr(cEntry,   "drive", 1, 0);
  rb_define_method(cEntry, "directory", Entry_directory_get, 0);
  rb_define_method(cEntry, "directoryPath", Entry_directoryPath_get, 0);
  rb_define_method(cEntry, "directoryParts", Entry_directoryParts_get, 0);
  rb_define_attr(cEntry,   "file", 1, 0);
  rb_define_method(cEntry, "shortFile", Entry_shortFile_get, 0);
  rb_define_method(cEntry, "fileName", Entry_fileName_get, 0);
  rb_define_method(cEntry, "fileExt", Entry_fileExt_get, 0);
  rb_define_method(cEntry, "creationTime", Entry_creationTime_get, 0);
  . . . and for "modificationTime", "lastAccessTime" and 
    "lastStatusChangeTime"
  rb_define_method(cEntry, "size", Entry_size_get, 0);
  rb_define_method(cEntry, "isReadOnly", Entry_isReadOnly_get, 0);
  . . . and for "isDirectory" and "isLink"
  rb_define_method(cEntry, "<=>", Entry_cmp, 1);
  rb_define_alias(cEntry,  "to_s", "path");
}