stata 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
 - data/README +21 -0
 - data/ext/Makefile +187 -0
 - data/ext/Makefile_c +9 -0
 - data/ext/Read.c +135 -0
 - data/ext/Read.h +23 -0
 - data/ext/Read.o +0 -0
 - data/ext/Read.rb.c +168 -0
 - data/ext/Read.rb.o +0 -0
 - data/ext/Stata.bundle +0 -0
 - data/ext/Stata.c +81 -0
 - data/ext/Stata.h +72 -0
 - data/ext/Stata.o +0 -0
 - data/ext/Stata.rb.c +28 -0
 - data/ext/Stata.rb.o +0 -0
 - data/ext/Write.c +114 -0
 - data/ext/Write.h +10 -0
 - data/ext/Write.o +0 -0
 - data/ext/Write.rb.c +259 -0
 - data/ext/Write.rb.o +0 -0
 - data/ext/extconf.rb +11 -0
 - data/ext/stata_c_test +0 -0
 - data/ext/test.rb +42 -0
 - metadata +99 -0
 
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (C) 2011 by Unspace Interactive
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         
     | 
| 
      
 4 
     | 
    
         
            +
            of this software and associated documentation files (the "Software"), to deal
         
     | 
| 
      
 5 
     | 
    
         
            +
            in the Software without restriction, including without limitation the rights
         
     | 
| 
      
 6 
     | 
    
         
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         
     | 
| 
      
 7 
     | 
    
         
            +
            copies of the Software, and to permit persons to whom the Software is
         
     | 
| 
      
 8 
     | 
    
         
            +
            furnished to do so, subject to the following conditions:
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be included in
         
     | 
| 
      
 11 
     | 
    
         
            +
            all copies or substantial portions of the Software.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         
     | 
| 
      
 14 
     | 
    
         
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         
     | 
| 
      
 15 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         
     | 
| 
      
 16 
     | 
    
         
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         
     | 
| 
      
 17 
     | 
    
         
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         
     | 
| 
      
 18 
     | 
    
         
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         
     | 
| 
      
 19 
     | 
    
         
            +
            THE SOFTWARE.
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
    
        data/README
    ADDED
    
    | 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            to make the test C app, run:
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              cd ext
         
     | 
| 
      
 5 
     | 
    
         
            +
              make -f Makefile_c -B
         
     | 
| 
      
 6 
     | 
    
         
            +
              ./stata_c_test file.dta
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            this will compile the application, read file.dta and create a copy of it from the same data in out.dta
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            to make the test Ruby app, run:
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              cd ext
         
     | 
| 
      
 14 
     | 
    
         
            +
              ruby extconf.rb
         
     | 
| 
      
 15 
     | 
    
         
            +
              make
         
     | 
| 
      
 16 
     | 
    
         
            +
              ./test.rb file.dta
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
              this will do the same, but using the Ruby extension
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            If the app finds any issues with the data, it will fail an assert, which will give you line numbers to the source.
         
     | 
    
        data/ext/Makefile
    ADDED
    
    | 
         @@ -0,0 +1,187 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            SHELL = /bin/sh
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            #### Start of system configuration section. ####
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            srcdir = .
         
     | 
| 
      
 7 
     | 
    
         
            +
            topdir = /Users/aanand/.rvm/rubies/ruby-1.9.2-p136/include/ruby-1.9.1
         
     | 
| 
      
 8 
     | 
    
         
            +
            hdrdir = /Users/aanand/.rvm/rubies/ruby-1.9.2-p136/include/ruby-1.9.1
         
     | 
| 
      
 9 
     | 
    
         
            +
            arch_hdrdir = /Users/aanand/.rvm/rubies/ruby-1.9.2-p136/include/ruby-1.9.1/$(arch)
         
     | 
| 
      
 10 
     | 
    
         
            +
            VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
         
     | 
| 
      
 11 
     | 
    
         
            +
            prefix = $(DESTDIR)/Users/aanand/.rvm/rubies/ruby-1.9.2-p136
         
     | 
| 
      
 12 
     | 
    
         
            +
            rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
         
     | 
| 
      
 13 
     | 
    
         
            +
            exec_prefix = $(prefix)
         
     | 
| 
      
 14 
     | 
    
         
            +
            vendorhdrdir = $(rubyhdrdir)/vendor_ruby
         
     | 
| 
      
 15 
     | 
    
         
            +
            sitehdrdir = $(rubyhdrdir)/site_ruby
         
     | 
| 
      
 16 
     | 
    
         
            +
            rubyhdrdir = $(includedir)/$(RUBY_BASE_NAME)-$(ruby_version)
         
     | 
| 
      
 17 
     | 
    
         
            +
            vendordir = $(rubylibprefix)/vendor_ruby
         
     | 
| 
      
 18 
     | 
    
         
            +
            sitedir = $(rubylibprefix)/site_ruby
         
     | 
| 
      
 19 
     | 
    
         
            +
            ridir = $(datarootdir)/$(RI_BASE_NAME)
         
     | 
| 
      
 20 
     | 
    
         
            +
            mandir = $(datarootdir)/man
         
     | 
| 
      
 21 
     | 
    
         
            +
            localedir = $(datarootdir)/locale
         
     | 
| 
      
 22 
     | 
    
         
            +
            libdir = $(exec_prefix)/lib
         
     | 
| 
      
 23 
     | 
    
         
            +
            psdir = $(docdir)
         
     | 
| 
      
 24 
     | 
    
         
            +
            pdfdir = $(docdir)
         
     | 
| 
      
 25 
     | 
    
         
            +
            dvidir = $(docdir)
         
     | 
| 
      
 26 
     | 
    
         
            +
            htmldir = $(docdir)
         
     | 
| 
      
 27 
     | 
    
         
            +
            infodir = $(datarootdir)/info
         
     | 
| 
      
 28 
     | 
    
         
            +
            docdir = $(datarootdir)/doc/$(PACKAGE)
         
     | 
| 
      
 29 
     | 
    
         
            +
            oldincludedir = $(DESTDIR)/usr/include
         
     | 
| 
      
 30 
     | 
    
         
            +
            includedir = $(prefix)/include
         
     | 
| 
      
 31 
     | 
    
         
            +
            localstatedir = $(prefix)/var
         
     | 
| 
      
 32 
     | 
    
         
            +
            sharedstatedir = $(prefix)/com
         
     | 
| 
      
 33 
     | 
    
         
            +
            sysconfdir = $(prefix)/etc
         
     | 
| 
      
 34 
     | 
    
         
            +
            datadir = $(datarootdir)
         
     | 
| 
      
 35 
     | 
    
         
            +
            datarootdir = $(prefix)/share
         
     | 
| 
      
 36 
     | 
    
         
            +
            libexecdir = $(exec_prefix)/libexec
         
     | 
| 
      
 37 
     | 
    
         
            +
            sbindir = $(exec_prefix)/sbin
         
     | 
| 
      
 38 
     | 
    
         
            +
            bindir = $(exec_prefix)/bin
         
     | 
| 
      
 39 
     | 
    
         
            +
            rubylibdir = $(rubylibprefix)/$(ruby_version)
         
     | 
| 
      
 40 
     | 
    
         
            +
            archdir = $(rubylibdir)/$(arch)
         
     | 
| 
      
 41 
     | 
    
         
            +
            sitelibdir = $(sitedir)/$(ruby_version)
         
     | 
| 
      
 42 
     | 
    
         
            +
            sitearchdir = $(sitelibdir)/$(sitearch)
         
     | 
| 
      
 43 
     | 
    
         
            +
            vendorlibdir = $(vendordir)/$(ruby_version)
         
     | 
| 
      
 44 
     | 
    
         
            +
            vendorarchdir = $(vendorlibdir)/$(sitearch)
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            CC = gcc
         
     | 
| 
      
 47 
     | 
    
         
            +
            CXX = g++
         
     | 
| 
      
 48 
     | 
    
         
            +
            LIBRUBY = $(LIBRUBY_SO)
         
     | 
| 
      
 49 
     | 
    
         
            +
            LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
         
     | 
| 
      
 50 
     | 
    
         
            +
            LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
         
     | 
| 
      
 51 
     | 
    
         
            +
            LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
         
     | 
| 
      
 52 
     | 
    
         
            +
            OUTFLAG = -o 
         
     | 
| 
      
 53 
     | 
    
         
            +
            COUTFLAG = -o 
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            RUBY_EXTCONF_H = 
         
     | 
| 
      
 56 
     | 
    
         
            +
            cflags   =  $(optflags) $(debugflags) $(warnflags)
         
     | 
| 
      
 57 
     | 
    
         
            +
            optflags = -O3
         
     | 
| 
      
 58 
     | 
    
         
            +
            debugflags = -ggdb
         
     | 
| 
      
 59 
     | 
    
         
            +
            warnflags = -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wshorten-64-to-32 -Wno-long-long
         
     | 
| 
      
 60 
     | 
    
         
            +
            CFLAGS   = -fno-common -isysroot /Developer/SDKs/MacOSX10.6.sdk -arch i386 -fno-common -pipe 
         
     | 
| 
      
 61 
     | 
    
         
            +
            INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
         
     | 
| 
      
 62 
     | 
    
         
            +
            DEFS     = 
         
     | 
| 
      
 63 
     | 
    
         
            +
            CPPFLAGS =  -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags)
         
     | 
| 
      
 64 
     | 
    
         
            +
            CXXFLAGS = $(CFLAGS) $(cxxflags)
         
     | 
| 
      
 65 
     | 
    
         
            +
            ldflags  = -L. -Wl,-syslibroot /Developer/SDKs/MacOSX10.6.sdk -arch i386 -L/usr/local/lib
         
     | 
| 
      
 66 
     | 
    
         
            +
            dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -Wl,-flat_namespace
         
     | 
| 
      
 67 
     | 
    
         
            +
            ARCH_FLAG = 
         
     | 
| 
      
 68 
     | 
    
         
            +
            DLDFLAGS = $(ldflags) $(dldflags)
         
     | 
| 
      
 69 
     | 
    
         
            +
            LDSHARED = $(CC) -dynamic -bundle
         
     | 
| 
      
 70 
     | 
    
         
            +
            LDSHAREDXX = $(CXX) -dynamic -bundle
         
     | 
| 
      
 71 
     | 
    
         
            +
            AR = ar
         
     | 
| 
      
 72 
     | 
    
         
            +
            EXEEXT = 
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            RUBY_BASE_NAME = ruby
         
     | 
| 
      
 75 
     | 
    
         
            +
            RUBY_INSTALL_NAME = ruby
         
     | 
| 
      
 76 
     | 
    
         
            +
            RUBY_SO_NAME = ruby.1.9.1
         
     | 
| 
      
 77 
     | 
    
         
            +
            arch = i386-darwin10.5.0
         
     | 
| 
      
 78 
     | 
    
         
            +
            sitearch = $(arch)
         
     | 
| 
      
 79 
     | 
    
         
            +
            ruby_version = 1.9.1
         
     | 
| 
      
 80 
     | 
    
         
            +
            ruby = /Users/aanand/.rvm/rubies/ruby-1.9.2-p136/bin/ruby
         
     | 
| 
      
 81 
     | 
    
         
            +
            RUBY = $(ruby)
         
     | 
| 
      
 82 
     | 
    
         
            +
            RM = rm -f
         
     | 
| 
      
 83 
     | 
    
         
            +
            RM_RF = $(RUBY) -run -e rm -- -rf
         
     | 
| 
      
 84 
     | 
    
         
            +
            RMDIRS = $(RUBY) -run -e rmdir -- -p
         
     | 
| 
      
 85 
     | 
    
         
            +
            MAKEDIRS = mkdir -p
         
     | 
| 
      
 86 
     | 
    
         
            +
            INSTALL = /usr/bin/install -c
         
     | 
| 
      
 87 
     | 
    
         
            +
            INSTALL_PROG = $(INSTALL) -m 0755
         
     | 
| 
      
 88 
     | 
    
         
            +
            INSTALL_DATA = $(INSTALL) -m 644
         
     | 
| 
      
 89 
     | 
    
         
            +
            COPY = cp
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            #### End of system configuration section. ####
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            preload = 
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            libpath = . $(libdir)
         
     | 
| 
      
 96 
     | 
    
         
            +
            LIBPATH =  -L. -L$(libdir)
         
     | 
| 
      
 97 
     | 
    
         
            +
            DEFFILE = 
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            CLEANFILES = mkmf.log
         
     | 
| 
      
 100 
     | 
    
         
            +
            DISTCLEANFILES = 
         
     | 
| 
      
 101 
     | 
    
         
            +
            DISTCLEANDIRS = 
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            extout = 
         
     | 
| 
      
 104 
     | 
    
         
            +
            extout_prefix = 
         
     | 
| 
      
 105 
     | 
    
         
            +
            target_prefix = 
         
     | 
| 
      
 106 
     | 
    
         
            +
            LOCAL_LIBS = 
         
     | 
| 
      
 107 
     | 
    
         
            +
            LIBS = $(LIBRUBYARG_SHARED)  -lpthread -ldl -lobjc 
         
     | 
| 
      
 108 
     | 
    
         
            +
            SRCS = Read.c Read.rb.c Stata.c Stata.rb.c Write.c Write.rb.c
         
     | 
| 
      
 109 
     | 
    
         
            +
            OBJS = Read.o Read.rb.o Stata.o Stata.rb.o Write.o Write.rb.o
         
     | 
| 
      
 110 
     | 
    
         
            +
            TARGET = Stata
         
     | 
| 
      
 111 
     | 
    
         
            +
            DLLIB = $(TARGET).bundle
         
     | 
| 
      
 112 
     | 
    
         
            +
            EXTSTATIC = 
         
     | 
| 
      
 113 
     | 
    
         
            +
            STATIC_LIB = 
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            BINDIR        = $(bindir)
         
     | 
| 
      
 116 
     | 
    
         
            +
            RUBYCOMMONDIR = $(sitedir)$(target_prefix)
         
     | 
| 
      
 117 
     | 
    
         
            +
            RUBYLIBDIR    = $(sitelibdir)$(target_prefix)
         
     | 
| 
      
 118 
     | 
    
         
            +
            RUBYARCHDIR   = $(sitearchdir)$(target_prefix)
         
     | 
| 
      
 119 
     | 
    
         
            +
            HDRDIR        = $(rubyhdrdir)/ruby$(target_prefix)
         
     | 
| 
      
 120 
     | 
    
         
            +
            ARCHHDRDIR    = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            TARGET_SO     = $(DLLIB)
         
     | 
| 
      
 123 
     | 
    
         
            +
            CLEANLIBS     = $(TARGET).bundle 
         
     | 
| 
      
 124 
     | 
    
         
            +
            CLEANOBJS     = *.o  *.bak
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            all:    $(DLLIB)
         
     | 
| 
      
 127 
     | 
    
         
            +
            static: $(STATIC_LIB)
         
     | 
| 
      
 128 
     | 
    
         
            +
            .PHONY: all install static install-so install-rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            .PHONY: clean clean-so clean-rb
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            clean-rb-default::
         
     | 
| 
      
 132 
     | 
    
         
            +
            clean-rb::
         
     | 
| 
      
 133 
     | 
    
         
            +
            clean-so::
         
     | 
| 
      
 134 
     | 
    
         
            +
            clean: clean-so clean-rb-default clean-rb
         
     | 
| 
      
 135 
     | 
    
         
            +
            		@-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            distclean-rb-default::
         
     | 
| 
      
 138 
     | 
    
         
            +
            distclean-rb::
         
     | 
| 
      
 139 
     | 
    
         
            +
            distclean-so::
         
     | 
| 
      
 140 
     | 
    
         
            +
            distclean: clean distclean-so distclean-rb-default distclean-rb
         
     | 
| 
      
 141 
     | 
    
         
            +
            		@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
         
     | 
| 
      
 142 
     | 
    
         
            +
            		@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
         
     | 
| 
      
 143 
     | 
    
         
            +
            		@-$(RMDIRS) $(DISTCLEANDIRS)
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
            realclean: distclean
         
     | 
| 
      
 146 
     | 
    
         
            +
            install: install-so install-rb
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            install-so: $(RUBYARCHDIR)
         
     | 
| 
      
 149 
     | 
    
         
            +
            install-so: $(RUBYARCHDIR)/$(DLLIB)
         
     | 
| 
      
 150 
     | 
    
         
            +
            $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
         
     | 
| 
      
 151 
     | 
    
         
            +
            	@-$(MAKEDIRS) $(@D)
         
     | 
| 
      
 152 
     | 
    
         
            +
            	$(INSTALL_PROG) $(DLLIB) $(@D)
         
     | 
| 
      
 153 
     | 
    
         
            +
            install-rb: pre-install-rb install-rb-default
         
     | 
| 
      
 154 
     | 
    
         
            +
            install-rb-default: pre-install-rb-default
         
     | 
| 
      
 155 
     | 
    
         
            +
            pre-install-rb: Makefile
         
     | 
| 
      
 156 
     | 
    
         
            +
            pre-install-rb-default: Makefile
         
     | 
| 
      
 157 
     | 
    
         
            +
            $(RUBYARCHDIR):
         
     | 
| 
      
 158 
     | 
    
         
            +
            	$(MAKEDIRS) $@
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            site-install: site-install-so site-install-rb
         
     | 
| 
      
 161 
     | 
    
         
            +
            site-install-so: install-so
         
     | 
| 
      
 162 
     | 
    
         
            +
            site-install-rb: install-rb
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            .SUFFIXES: .c .m .cc .cxx .cpp .C .o
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
            .cc.o:
         
     | 
| 
      
 167 
     | 
    
         
            +
            	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
            .cxx.o:
         
     | 
| 
      
 170 
     | 
    
         
            +
            	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            .cpp.o:
         
     | 
| 
      
 173 
     | 
    
         
            +
            	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
            .C.o:
         
     | 
| 
      
 176 
     | 
    
         
            +
            	$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
            .c.o:
         
     | 
| 
      
 179 
     | 
    
         
            +
            	$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            $(DLLIB): $(OBJS) Makefile
         
     | 
| 
      
 182 
     | 
    
         
            +
            	@-$(RM) $(@)
         
     | 
| 
      
 183 
     | 
    
         
            +
            	$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
            $(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
         
     | 
    
        data/ext/Makefile_c
    ADDED
    
    
    
        data/ext/Read.c
    ADDED
    
    | 
         @@ -0,0 +1,135 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #include "Read.h"
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include "Stata.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <math.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            int16_t read_int16_t() { int16_t t=0; fread(&t, sizeof(t), 1, fp); return ((swap_endian_needed==1) ? ((t>>8) | (t<<8)) : t); }
         
     | 
| 
      
 10 
     | 
    
         
            +
            int32_t read_int32_t() { int32_t t=0; fread(&t, sizeof(t), 1, fp); return (swap_endian_needed==1) ? (int32_t)__builtin_bswap32(t) : t; }
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            uint16_t read_uint16_t() { uint16_t t=0; fread(&t, sizeof(t), 1, fp); return (swap_endian_needed==1) ? (t>>8)|(t<<8) : t; }
         
     | 
| 
      
 13 
     | 
    
         
            +
            uint32_t read_uint32_t() { uint32_t t=0; fread(&t, sizeof(t), 1, fp); return (swap_endian_needed==1) ? __builtin_bswap32(t) : t; }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            char * read_string(int length) { char * t = (char*)malloc(length+1); fread(t, length, 1, fp); t[length] = 0; return t; }
         
     | 
| 
      
 16 
     | 
    
         
            +
            char ** read_strings(int num, int length) { char ** t = (char **)malloc(sizeof(char *)*num); int i; for (i = 0 ; i < num ; i++) t[i] = read_string(length); return t; }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            float read_float_t() { uint32_t t=0; fread(&t, sizeof(t), 1, fp); if (swap_endian_needed==1) t = __builtin_bswap32(t); return *((float *)(void *)&t); }
         
     | 
| 
      
 19 
     | 
    
         
            +
            double read_double_t() { uint64_t t=0; fread(&t, sizeof(t), 1, fp); if (swap_endian_needed==1) t = __builtin_bswap64(t); return *((double *)(void *)&t); }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            struct stata_file * read_stata_file(char * filename)
         
     | 
| 
      
 22 
     | 
    
         
            +
            {
         
     | 
| 
      
 23 
     | 
    
         
            +
              if (verbose) printf("read file '%s'\n", filename);
         
     | 
| 
      
 24 
     | 
    
         
            +
              
         
     | 
| 
      
 25 
     | 
    
         
            +
              long i,j;
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              struct stata_file * f = (struct stata_file *)malloc(sizeof(struct stata_file));
         
     | 
| 
      
 28 
     | 
    
         
            +
              memset(f, 0, sizeof(struct stata_file));
         
     | 
| 
      
 29 
     | 
    
         
            +
              f->filename = (char*)malloc(strlen(filename)+1);
         
     | 
| 
      
 30 
     | 
    
         
            +
              strcpy(f->filename, filename);
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              fp = fopen(f->filename, "rb");
         
     | 
| 
      
 33 
     | 
    
         
            +
              if (fp == NULL) { set_error(f, "error reading file"); return f; }
         
     | 
| 
      
 34 
     | 
    
         
            +
              
         
     | 
| 
      
 35 
     | 
    
         
            +
              /*fseek(fp, 0 , SEEK_END);
         
     | 
| 
      
 36 
     | 
    
         
            +
              long lSize = ftell(fp);
         
     | 
| 
      
 37 
     | 
    
         
            +
              rewind(fp);
         
     | 
| 
      
 38 
     | 
    
         
            +
              printf("file is %ld bytes long\n", lSize);*/
         
     | 
| 
      
 39 
     | 
    
         
            +
              
         
     | 
| 
      
 40 
     | 
    
         
            +
              
         
     | 
| 
      
 41 
     | 
    
         
            +
              /* 5.1 Header */
         
     | 
| 
      
 42 
     | 
    
         
            +
              f->ds_format = fgetc(fp);  if (f->ds_format != 0x72) { set_error(f, "invalid file ds_format"); return f; }
         
     | 
| 
      
 43 
     | 
    
         
            +
              f->byteorder = fgetc(fp);  if (f->byteorder != 0x01 && f->byteorder != 0x02) { set_error(f, "invalid file byteorder"); return f; }
         
     | 
| 
      
 44 
     | 
    
         
            +
              if (f->byteorder != get_host_endian()) swap_endian_needed = 1;
         
     | 
| 
      
 45 
     | 
    
         
            +
              f->filetype = fgetc(fp);   if (f->filetype != 0x01) { set_error(f, "invalid file filetype"); return f; }
         
     | 
| 
      
 46 
     | 
    
         
            +
              f->unused = fgetc(fp);     if (f->unused != 0x00) { set_error(f, "invalid unused values"); return f; }
         
     | 
| 
      
 47 
     | 
    
         
            +
              f->nvar = read_uint16_t(); if (f->nvar <= 0) { set_error(f, "invalid nvar (< 1)"); return f; }
         
     | 
| 
      
 48 
     | 
    
         
            +
              f->nobs = read_uint32_t(); if (f->nobs <= 0) { set_error(f, "invalid nobs (< 1)"); return f; }
         
     | 
| 
      
 49 
     | 
    
         
            +
              fread(&f->data_label, sizeof(f->data_label), 1, fp);
         
     | 
| 
      
 50 
     | 
    
         
            +
              fread(&f->time_stamp, sizeof(f->time_stamp), 1, fp);
         
     | 
| 
      
 51 
     | 
    
         
            +
              
         
     | 
| 
      
 52 
     | 
    
         
            +
              
         
     | 
| 
      
 53 
     | 
    
         
            +
              /* 5.2 Descriptors */
         
     | 
| 
      
 54 
     | 
    
         
            +
              f->typlist = (uint8_t *)malloc(f->nvar);
         
     | 
| 
      
 55 
     | 
    
         
            +
              fread(f->typlist, 1, f->nvar, fp);
         
     | 
| 
      
 56 
     | 
    
         
            +
              f->varlist = read_strings(f->nvar, 33);
         
     | 
| 
      
 57 
     | 
    
         
            +
              f->srtlist = (uint16_t *)malloc(sizeof(uint16_t)*(f->nvar+1));
         
     | 
| 
      
 58 
     | 
    
         
            +
              for (i = 0 ; i <= f->nvar ; i++) f->srtlist[i] = read_uint16_t();
         
     | 
| 
      
 59 
     | 
    
         
            +
              f->fmtlist = read_strings(f->nvar, 49);
         
     | 
| 
      
 60 
     | 
    
         
            +
              f->lbllist = read_strings(f->nvar, 33);
         
     | 
| 
      
 61 
     | 
    
         
            +
              
         
     | 
| 
      
 62 
     | 
    
         
            +
              
         
     | 
| 
      
 63 
     | 
    
         
            +
              /* 5.3 Variable Labels */
         
     | 
| 
      
 64 
     | 
    
         
            +
              f->variable_labels = read_strings(f->nvar, 81);
         
     | 
| 
      
 65 
     | 
    
         
            +
              
         
     | 
| 
      
 66 
     | 
    
         
            +
              
         
     | 
| 
      
 67 
     | 
    
         
            +
              /* 5.4 Expansion Fields */
         
     | 
| 
      
 68 
     | 
    
         
            +
              uint8_t data_type;
         
     | 
| 
      
 69 
     | 
    
         
            +
              uint32_t len;
         
     | 
| 
      
 70 
     | 
    
         
            +
              do {
         
     | 
| 
      
 71 
     | 
    
         
            +
                data_type = fgetc(fp);
         
     | 
| 
      
 72 
     | 
    
         
            +
                if (fread(&len, 4, 1, fp) != 1) { set_error(f, "fread from file failed"); return f; }
         
     | 
| 
      
 73 
     | 
    
         
            +
                if (len > 0) for (i = 0 ; i < len ; i++) fgetc(fp);
         
     | 
| 
      
 74 
     | 
    
         
            +
              } while(data_type != 0 || len != 0 || feof(fp));
         
     | 
| 
      
 75 
     | 
    
         
            +
              /*printf ("read %d bytes of expansion fields\n", count);*/
         
     | 
| 
      
 76 
     | 
    
         
            +
              
         
     | 
| 
      
 77 
     | 
    
         
            +
              
         
     | 
| 
      
 78 
     | 
    
         
            +
              /* 5.5 Data */
         
     | 
| 
      
 79 
     | 
    
         
            +
              /*printf("  read 5.5 Data (%dx%d)\n", f->nobs, f->nvar);*/
         
     | 
| 
      
 80 
     | 
    
         
            +
              f->obs = (struct stata_obs *)malloc(sizeof(struct stata_obs)*f->nobs);
         
     | 
| 
      
 81 
     | 
    
         
            +
              for (j = 0 ; j < f->nobs ; j++)
         
     | 
| 
      
 82 
     | 
    
         
            +
              {
         
     | 
| 
      
 83 
     | 
    
         
            +
                f->obs[j].var = (struct stata_var *)malloc(sizeof(struct stata_var)*f->nvar);
         
     | 
| 
      
 84 
     | 
    
         
            +
                for (i = 0 ; i < f->nvar ; i++)
         
     | 
| 
      
 85 
     | 
    
         
            +
                {
         
     | 
| 
      
 86 
     | 
    
         
            +
                  struct stata_var * var = &f->obs[j].var[i];
         
     | 
| 
      
 87 
     | 
    
         
            +
                  memset(var, 0, sizeof(struct stata_var));
         
     | 
| 
      
 88 
     | 
    
         
            +
                  
         
     | 
| 
      
 89 
     | 
    
         
            +
                  if (f->typlist[i] != 0 && 
         
     | 
| 
      
 90 
     | 
    
         
            +
                      f->typlist[i] < 245) { var->v_type = V_STR;    var->v_str = read_string(f->typlist[i]); if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
         
     | 
| 
      
 91 
     | 
    
         
            +
                  else if (f->typlist[i] == 251) { var->v_type = V_BYTE;   if (fread(&var->v_byte, sizeof(var->v_byte), 1, fp) != 1) { set_error(f, "fread from file failed"); }; if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
         
     | 
| 
      
 92 
     | 
    
         
            +
                  else if (f->typlist[i] == 252) { var->v_type = V_INT;    var->v_int = read_int16_t();     if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
         
     | 
| 
      
 93 
     | 
    
         
            +
                  else if (f->typlist[i] == 253) { var->v_type = V_LONG;   var->v_long = read_int32_t();    if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
         
     | 
| 
      
 94 
     | 
    
         
            +
                  else if (f->typlist[i] == 254) { var->v_type = V_FLOAT;  var->v_float = read_float_t();   if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
         
     | 
| 
      
 95 
     | 
    
         
            +
                  else if (f->typlist[i] == 255) { var->v_type = V_DOUBLE; var->v_double = read_double_t(); if (feof(fp)) { set_error(f, "end of file reached too soon"); return f; }; }
         
     | 
| 
      
 96 
     | 
    
         
            +
                  else fprintf(stderr, "error.\n");
         
     | 
| 
      
 97 
     | 
    
         
            +
                  
         
     | 
| 
      
 98 
     | 
    
         
            +
                  if (ferror(fp)) perror("error occurred");
         
     | 
| 
      
 99 
     | 
    
         
            +
                  if (feof(fp)) { fprintf(stderr, "eof error at var %ld (error:%d)\n", i, ferror(fp)); break; }
         
     | 
| 
      
 100 
     | 
    
         
            +
                }
         
     | 
| 
      
 101 
     | 
    
         
            +
                if (feof(fp)) { fprintf(stderr, "eof error at obs %ld (error:%d)\n", j, ferror(fp)); exit(1); }
         
     | 
| 
      
 102 
     | 
    
         
            +
              }
         
     | 
| 
      
 103 
     | 
    
         
            +
              
         
     | 
| 
      
 104 
     | 
    
         
            +
              
         
     | 
| 
      
 105 
     | 
    
         
            +
              /* 5.6 Value labels */
         
     | 
| 
      
 106 
     | 
    
         
            +
              if (!feof(fp))
         
     | 
| 
      
 107 
     | 
    
         
            +
              {
         
     | 
| 
      
 108 
     | 
    
         
            +
                while (!feof(fp))
         
     | 
| 
      
 109 
     | 
    
         
            +
                {
         
     | 
| 
      
 110 
     | 
    
         
            +
                  int32_t len = read_int32_t();
         
     | 
| 
      
 111 
     | 
    
         
            +
                  if (feof(fp) || len == 0) break;
         
     | 
| 
      
 112 
     | 
    
         
            +
                  
         
     | 
| 
      
 113 
     | 
    
         
            +
                  f->num_vlt++;
         
     | 
| 
      
 114 
     | 
    
         
            +
                  f->vlt = (struct stata_vlt *)realloc(f->vlt, sizeof(struct stata_vlt)*f->num_vlt);
         
     | 
| 
      
 115 
     | 
    
         
            +
                  struct stata_vlt * vlt = &f->vlt[f->num_vlt-1];
         
     | 
| 
      
 116 
     | 
    
         
            +
                  
         
     | 
| 
      
 117 
     | 
    
         
            +
                  if (fread(vlt->name, 33, 1, fp) != 1) { set_error(f, "fread from file failed"); return f; };
         
     | 
| 
      
 118 
     | 
    
         
            +
                  fgetc(fp); fgetc(fp); fgetc(fp); /* padding */
         
     | 
| 
      
 119 
     | 
    
         
            +
                  
         
     | 
| 
      
 120 
     | 
    
         
            +
                  vlt->n = read_int32_t();
         
     | 
| 
      
 121 
     | 
    
         
            +
                  vlt->txtlen = read_int32_t(); if (vlt->txtlen >= 32000) { set_error(f, "value label table txtlen is > 32000"); return f; };
         
     | 
| 
      
 122 
     | 
    
         
            +
                  vlt->off = (int32_t*)malloc(sizeof(int32_t)*vlt->n);
         
     | 
| 
      
 123 
     | 
    
         
            +
                  for (i = 0 ; i < vlt->n ; i++) vlt->off[i] = read_int32_t();
         
     | 
| 
      
 124 
     | 
    
         
            +
                  vlt->val = (int32_t*)malloc(sizeof(int32_t)*vlt->n);
         
     | 
| 
      
 125 
     | 
    
         
            +
                  for (i = 0 ; i < vlt->n ; i++) vlt->val[i] = read_int32_t();
         
     | 
| 
      
 126 
     | 
    
         
            +
                  vlt->txtbuf = (char*)malloc(vlt->txtlen);
         
     | 
| 
      
 127 
     | 
    
         
            +
                  fread(vlt->txtbuf, vlt->txtlen, 1, fp);
         
     | 
| 
      
 128 
     | 
    
         
            +
                }
         
     | 
| 
      
 129 
     | 
    
         
            +
              }
         
     | 
| 
      
 130 
     | 
    
         
            +
              /*printf("  read 5.6 Value labels (%d)\n", f->num_vlt);*/
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
              
         
     | 
| 
      
 133 
     | 
    
         
            +
              fclose(fp);
         
     | 
| 
      
 134 
     | 
    
         
            +
              return f;
         
     | 
| 
      
 135 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/Read.h
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #ifndef STATA_READ_H
         
     | 
| 
      
 3 
     | 
    
         
            +
            #define STATA_READ_H
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            #include <inttypes.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            extern int16_t read_int16_t();
         
     | 
| 
      
 8 
     | 
    
         
            +
            extern int32_t read_int32_t();
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            extern uint16_t read_uint16_t();
         
     | 
| 
      
 11 
     | 
    
         
            +
            extern uint32_t read_uint32_t();
         
     | 
| 
      
 12 
     | 
    
         
            +
            extern uint64_t read_uint64_t();
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            extern char * read_string(int length);
         
     | 
| 
      
 15 
     | 
    
         
            +
            extern char ** read_strings(int num, int length);
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            extern float read_float_t();
         
     | 
| 
      
 18 
     | 
    
         
            +
            extern double read_double_t();
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            struct stata_file;
         
     | 
| 
      
 21 
     | 
    
         
            +
            extern struct stata_file * read_stata_file(char * filename);
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            #endif
         
     | 
    
        data/ext/Read.o
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/Read.rb.c
    ADDED
    
    | 
         @@ -0,0 +1,168 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #include <math.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <ruby.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include "Stata.h"
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include "Read.h"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            #ifdef HAVE_RUBY_ENCODING_H
         
     | 
| 
      
 8 
     | 
    
         
            +
            # include <ruby/encoding.h>
         
     | 
| 
      
 9 
     | 
    
         
            +
            # define ENCODED_STR_NEW2(str, encoding) \
         
     | 
| 
      
 10 
     | 
    
         
            +
               ({ \
         
     | 
| 
      
 11 
     | 
    
         
            +
                VALUE _string = rb_str_new2((const char *)str); \
         
     | 
| 
      
 12 
     | 
    
         
            +
                 int _enc = rb_enc_find_index(encoding); \
         
     | 
| 
      
 13 
     | 
    
         
            +
                 rb_enc_associate_index(_string, _enc); \
         
     | 
| 
      
 14 
     | 
    
         
            +
                 _string; \
         
     | 
| 
      
 15 
     | 
    
         
            +
               })
         
     | 
| 
      
 16 
     | 
    
         
            +
            #else
         
     | 
| 
      
 17 
     | 
    
         
            +
            # define ENCODED_STR_NEW2(str, encoding) \
         
     | 
| 
      
 18 
     | 
    
         
            +
               rb_str_new2((const char *)str)
         
     | 
| 
      
 19 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            VALUE method_read(VALUE self, VALUE file)
         
     | 
| 
      
 22 
     | 
    
         
            +
            {
         
     | 
| 
      
 23 
     | 
    
         
            +
            	long i,j;
         
     | 
| 
      
 24 
     | 
    
         
            +
              
         
     | 
| 
      
 25 
     | 
    
         
            +
              if (TYPE(file) != T_STRING) rb_raise(rb_eArgError, "filename is not a string, but instead of type '%d' (in C)", TYPE(file));
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              struct stata_file * f = read_stata_file(rb_string_value_cstr(&file));
         
     | 
| 
      
 28 
     | 
    
         
            +
              if (f == NULL) rb_raise(rb_eRuntimeError, "Read Error");
         
     | 
| 
      
 29 
     | 
    
         
            +
              if (f->error) rb_raise(rb_eRuntimeError, "%s", f->error);
         
     | 
| 
      
 30 
     | 
    
         
            +
              
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              /* 5.1 Headers */
         
     | 
| 
      
 33 
     | 
    
         
            +
              VALUE r = rb_hash_new();
         
     | 
| 
      
 34 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("file_name", "ASCII-8BIT"), ENCODED_STR_NEW2(f->filename, "ASCII-8BIT"));
         
     | 
| 
      
 35 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("data_label", "ASCII-8BIT"), ENCODED_STR_NEW2(f->data_label, "ASCII-8BIT"));
         
     | 
| 
      
 36 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("time_stamp", "ASCII-8BIT"), ENCODED_STR_NEW2(f->time_stamp, "ASCII-8BIT"));
         
     | 
| 
      
 37 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("nvar", "ASCII-8BIT"), INT2NUM(f->nvar));
         
     | 
| 
      
 38 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("nobs", "ASCII-8BIT"), INT2NUM(f->nobs));
         
     | 
| 
      
 39 
     | 
    
         
            +
              
         
     | 
| 
      
 40 
     | 
    
         
            +
              VALUE data = rb_ary_new();
         
     | 
| 
      
 41 
     | 
    
         
            +
              for (i = 0 ; i < f->nobs ; i++)
         
     | 
| 
      
 42 
     | 
    
         
            +
              {
         
     | 
| 
      
 43 
     | 
    
         
            +
                VALUE row = rb_ary_new();
         
     | 
| 
      
 44 
     | 
    
         
            +
                for (j = 0 ; j < f->nvar ; j++)
         
     | 
| 
      
 45 
     | 
    
         
            +
                {
         
     | 
| 
      
 46 
     | 
    
         
            +
                  char symbol_name[100];
         
     | 
| 
      
 47 
     | 
    
         
            +
                  sprintf(symbol_name, "%d", f->obs[i].var[j].v_type);
         
     | 
| 
      
 48 
     | 
    
         
            +
                  VALUE var = Qnil;
         
     | 
| 
      
 49 
     | 
    
         
            +
                  sprintf(symbol_name, "dot_");
         
     | 
| 
      
 50 
     | 
    
         
            +
                  
         
     | 
| 
      
 51 
     | 
    
         
            +
                  if (f->obs[i].var[j].v_type == V_STR && f->obs[i].var[j].v_str != NULL)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    var = ENCODED_STR_NEW2(f->obs[i].var[j].v_str, "ASCII-8BIT");
         
     | 
| 
      
 53 
     | 
    
         
            +
                  else if (f->obs[i].var[j].v_type == V_BYTE)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  {
         
     | 
| 
      
 55 
     | 
    
         
            +
                    if (f->obs[i].var[j].v_byte >= -127 && f->obs[i].var[j].v_byte <= 100)
         
     | 
| 
      
 56 
     | 
    
         
            +
                      var = INT2NUM((int)f->obs[i].var[j].v_byte);
         
     | 
| 
      
 57 
     | 
    
         
            +
                    else if (f->obs[i].var[j].v_byte > 100)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    {
         
     | 
| 
      
 59 
     | 
    
         
            +
                      int dot = f->obs[i].var[j].v_byte - 101;
         
     | 
| 
      
 60 
     | 
    
         
            +
                      if (dot == 0) symbol_name[3] = 0;
         
     | 
| 
      
 61 
     | 
    
         
            +
                      else symbol_name[4] = dot+96;
         
     | 
| 
      
 62 
     | 
    
         
            +
                      symbol_name[5] = 0;
         
     | 
| 
      
 63 
     | 
    
         
            +
                      var = rb_str_intern(ENCODED_STR_NEW2(symbol_name, "ASCII-8BIT"));
         
     | 
| 
      
 64 
     | 
    
         
            +
                    }
         
     | 
| 
      
 65 
     | 
    
         
            +
                  }
         
     | 
| 
      
 66 
     | 
    
         
            +
                  else if (f->obs[i].var[j].v_type == V_INT)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  {
         
     | 
| 
      
 68 
     | 
    
         
            +
                    if (f->obs[i].var[j].v_int >= -32767 && f->obs[i].var[j].v_int <= 32740)
         
     | 
| 
      
 69 
     | 
    
         
            +
                      var = INT2NUM((int)f->obs[i].var[j].v_int);
         
     | 
| 
      
 70 
     | 
    
         
            +
                    else if (f->obs[i].var[j].v_int > 32740)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    {
         
     | 
| 
      
 72 
     | 
    
         
            +
                      int dot = f->obs[i].var[j].v_int - 32741;
         
     | 
| 
      
 73 
     | 
    
         
            +
                      if (dot == 0) symbol_name[3] = 0;
         
     | 
| 
      
 74 
     | 
    
         
            +
                      else symbol_name[4] = dot+96;
         
     | 
| 
      
 75 
     | 
    
         
            +
                      symbol_name[5] = 0;
         
     | 
| 
      
 76 
     | 
    
         
            +
                      var = rb_str_intern(ENCODED_STR_NEW2(symbol_name, "ASCII-8BIT"));
         
     | 
| 
      
 77 
     | 
    
         
            +
                    }
         
     | 
| 
      
 78 
     | 
    
         
            +
                  }
         
     | 
| 
      
 79 
     | 
    
         
            +
                  else if (f->obs[i].var[j].v_type == V_LONG)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  {
         
     | 
| 
      
 81 
     | 
    
         
            +
                    if (f->obs[i].var[j].v_long >= -2147483647 && f->obs[i].var[j].v_long <= 2147483620)
         
     | 
| 
      
 82 
     | 
    
         
            +
                      var = LONG2NUM((int)f->obs[i].var[j].v_long);
         
     | 
| 
      
 83 
     | 
    
         
            +
                    else if (f->obs[i].var[j].v_long > 2147483620)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    {
         
     | 
| 
      
 85 
     | 
    
         
            +
                      int dot = f->obs[i].var[j].v_long - 2147483621;
         
     | 
| 
      
 86 
     | 
    
         
            +
                      if (dot == 0) symbol_name[3] = 0;
         
     | 
| 
      
 87 
     | 
    
         
            +
                      else symbol_name[4] = dot+96;
         
     | 
| 
      
 88 
     | 
    
         
            +
                      symbol_name[5] = 0;
         
     | 
| 
      
 89 
     | 
    
         
            +
                      var = rb_str_intern(ENCODED_STR_NEW2(symbol_name, "ASCII-8BIT"));
         
     | 
| 
      
 90 
     | 
    
         
            +
                    }
         
     | 
| 
      
 91 
     | 
    
         
            +
                  }
         
     | 
| 
      
 92 
     | 
    
         
            +
                  else if (f->obs[i].var[j].v_type == V_FLOAT)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  {
         
     | 
| 
      
 94 
     | 
    
         
            +
                    if (f->obs[i].var[j].v_float < pow(2, 127))
         
     | 
| 
      
 95 
     | 
    
         
            +
                    {
         
     | 
| 
      
 96 
     | 
    
         
            +
                      var = rb_float_new(f->obs[i].var[j].v_float);
         
     | 
| 
      
 97 
     | 
    
         
            +
                    }
         
     | 
| 
      
 98 
     | 
    
         
            +
                    else if (f->obs[i].var[j].v_float >= pow(2, 127))
         
     | 
| 
      
 99 
     | 
    
         
            +
                    {
         
     | 
| 
      
 100 
     | 
    
         
            +
                      int dot = (f->obs[i].var[j].v_float - (float)pow(2, 127)) / (float)pow(2, 115);
         
     | 
| 
      
 101 
     | 
    
         
            +
                      if (dot == 0) symbol_name[3] = 0;
         
     | 
| 
      
 102 
     | 
    
         
            +
                      else symbol_name[4] = dot+96;
         
     | 
| 
      
 103 
     | 
    
         
            +
                      symbol_name[5] = 0;
         
     | 
| 
      
 104 
     | 
    
         
            +
                      var = rb_str_intern(ENCODED_STR_NEW2(symbol_name, "ASCII-8BIT"));
         
     | 
| 
      
 105 
     | 
    
         
            +
                    }
         
     | 
| 
      
 106 
     | 
    
         
            +
                  }
         
     | 
| 
      
 107 
     | 
    
         
            +
                  else if (f->obs[i].var[j].v_type == V_DOUBLE)
         
     | 
| 
      
 108 
     | 
    
         
            +
                  {
         
     | 
| 
      
 109 
     | 
    
         
            +
                    if (f->obs[i].var[j].v_double < pow(2, 1023))
         
     | 
| 
      
 110 
     | 
    
         
            +
                    {
         
     | 
| 
      
 111 
     | 
    
         
            +
                      var = rb_float_new(f->obs[i].var[j].v_double);
         
     | 
| 
      
 112 
     | 
    
         
            +
                    }
         
     | 
| 
      
 113 
     | 
    
         
            +
                    else if (f->obs[i].var[j].v_double >= pow(2, 1023))
         
     | 
| 
      
 114 
     | 
    
         
            +
                    {
         
     | 
| 
      
 115 
     | 
    
         
            +
                      int dot = (int)((f->obs[i].var[j].v_double - pow(2, 1023)) / pow(2, 1011));
         
     | 
| 
      
 116 
     | 
    
         
            +
                      if (dot == 0) symbol_name[3] = 0;
         
     | 
| 
      
 117 
     | 
    
         
            +
                      else symbol_name[4] = dot+96;
         
     | 
| 
      
 118 
     | 
    
         
            +
                      symbol_name[5] = 0;
         
     | 
| 
      
 119 
     | 
    
         
            +
                      var = rb_str_intern(ENCODED_STR_NEW2(symbol_name, "ASCII-8BIT"));
         
     | 
| 
      
 120 
     | 
    
         
            +
                    }
         
     | 
| 
      
 121 
     | 
    
         
            +
                  }
         
     | 
| 
      
 122 
     | 
    
         
            +
                  
         
     | 
| 
      
 123 
     | 
    
         
            +
                  rb_ary_push(row, var);
         
     | 
| 
      
 124 
     | 
    
         
            +
                }
         
     | 
| 
      
 125 
     | 
    
         
            +
                rb_ary_push(data, row);
         
     | 
| 
      
 126 
     | 
    
         
            +
              }
         
     | 
| 
      
 127 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("data", "ASCII-8BIT"), data);
         
     | 
| 
      
 128 
     | 
    
         
            +
              
         
     | 
| 
      
 129 
     | 
    
         
            +
              
         
     | 
| 
      
 130 
     | 
    
         
            +
              VALUE fields = rb_ary_new();
         
     | 
| 
      
 131 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++)
         
     | 
| 
      
 132 
     | 
    
         
            +
              {
         
     | 
| 
      
 133 
     | 
    
         
            +
                VALUE field = rb_hash_new();
         
     | 
| 
      
 134 
     | 
    
         
            +
                rb_hash_aset(field, ENCODED_STR_NEW2("id", "ASCII-8BIT"), INT2NUM(i+1));
         
     | 
| 
      
 135 
     | 
    
         
            +
                rb_hash_aset(field, ENCODED_STR_NEW2("type", "ASCII-8BIT"), INT2NUM(f->typlist[i]));
         
     | 
| 
      
 136 
     | 
    
         
            +
                rb_hash_aset(field, ENCODED_STR_NEW2("name", "ASCII-8BIT"), ENCODED_STR_NEW2(f->varlist[i], "ASCII-8BIT"));
         
     | 
| 
      
 137 
     | 
    
         
            +
                rb_hash_aset(field, ENCODED_STR_NEW2("format", "ASCII-8BIT"), ENCODED_STR_NEW2(f->fmtlist[i], "ASCII-8BIT"));
         
     | 
| 
      
 138 
     | 
    
         
            +
                rb_hash_aset(field, ENCODED_STR_NEW2("variable_label", "ASCII-8BIT"), ENCODED_STR_NEW2(f->variable_labels[i], "ASCII-8BIT"));
         
     | 
| 
      
 139 
     | 
    
         
            +
                rb_hash_aset(field, ENCODED_STR_NEW2("value_label", "ASCII-8BIT"), ENCODED_STR_NEW2(f->lbllist[i], "ASCII-8BIT"));
         
     | 
| 
      
 140 
     | 
    
         
            +
                rb_hash_aset(field, ENCODED_STR_NEW2("sort", "ASCII-8BIT"), INT2NUM(f->srtlist[i]));
         
     | 
| 
      
 141 
     | 
    
         
            +
                rb_ary_push(fields, field);
         
     | 
| 
      
 142 
     | 
    
         
            +
              }
         
     | 
| 
      
 143 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("fields", "ASCII-8BIT"), fields);
         
     | 
| 
      
 144 
     | 
    
         
            +
              
         
     | 
| 
      
 145 
     | 
    
         
            +
              
         
     | 
| 
      
 146 
     | 
    
         
            +
              VALUE vlt = rb_ary_new();
         
     | 
| 
      
 147 
     | 
    
         
            +
              for (i = 0 ; i < f->num_vlt ; i++)
         
     | 
| 
      
 148 
     | 
    
         
            +
              {
         
     | 
| 
      
 149 
     | 
    
         
            +
                VALUE v = rb_hash_new();
         
     | 
| 
      
 150 
     | 
    
         
            +
                rb_hash_aset(v, ENCODED_STR_NEW2("name", "ASCII-8BIT"), ENCODED_STR_NEW2(f->vlt[i].name, "ASCII-8BIT"));
         
     | 
| 
      
 151 
     | 
    
         
            +
                VALUE table = rb_ary_new();
         
     | 
| 
      
 152 
     | 
    
         
            +
                for (j = 0 ; j < f->vlt[i].n ; j++)
         
     | 
| 
      
 153 
     | 
    
         
            +
                {
         
     | 
| 
      
 154 
     | 
    
         
            +
                  VALUE row = rb_ary_new();
         
     | 
| 
      
 155 
     | 
    
         
            +
                  rb_ary_push(row, INT2NUM(f->vlt[i].val[j]));
         
     | 
| 
      
 156 
     | 
    
         
            +
                  rb_ary_push(row, ENCODED_STR_NEW2(f->vlt[i].txtbuf + f->vlt[i].off[j], "ASCII-8BIT"));
         
     | 
| 
      
 157 
     | 
    
         
            +
                  
         
     | 
| 
      
 158 
     | 
    
         
            +
                  rb_ary_push(table, row);
         
     | 
| 
      
 159 
     | 
    
         
            +
                }
         
     | 
| 
      
 160 
     | 
    
         
            +
                
         
     | 
| 
      
 161 
     | 
    
         
            +
                rb_hash_aset(v, ENCODED_STR_NEW2("table", "ASCII-8BIT"), table);
         
     | 
| 
      
 162 
     | 
    
         
            +
                rb_ary_push(vlt, v);
         
     | 
| 
      
 163 
     | 
    
         
            +
              }
         
     | 
| 
      
 164 
     | 
    
         
            +
              rb_hash_aset(r, ENCODED_STR_NEW2("value_labels", "ASCII-8BIT"), vlt);
         
     | 
| 
      
 165 
     | 
    
         
            +
              
         
     | 
| 
      
 166 
     | 
    
         
            +
              free_stata(f);
         
     | 
| 
      
 167 
     | 
    
         
            +
              return r;
         
     | 
| 
      
 168 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/Read.rb.o
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/Stata.bundle
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/Stata.c
    ADDED
    
    | 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <math.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include <inttypes.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            #include "Stata.h"
         
     | 
| 
      
 9 
     | 
    
         
            +
            #include "Read.h"
         
     | 
| 
      
 10 
     | 
    
         
            +
            #include "Write.h"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            FILE *fp;
         
     | 
| 
      
 13 
     | 
    
         
            +
            int swap_endian_needed = 0;
         
     | 
| 
      
 14 
     | 
    
         
            +
            int verbose = 0;
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            char get_host_endian()
         
     | 
| 
      
 17 
     | 
    
         
            +
            {
         
     | 
| 
      
 18 
     | 
    
         
            +
              int i = 1;
         
     | 
| 
      
 19 
     | 
    
         
            +
              char *p = (char *) &i;
         
     | 
| 
      
 20 
     | 
    
         
            +
              return (p[0] == 1) ? 0x02 : 0x01;
         
     | 
| 
      
 21 
     | 
    
         
            +
            }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            int set_error(struct stata_file * f, const char * error)
         
     | 
| 
      
 24 
     | 
    
         
            +
            {
         
     | 
| 
      
 25 
     | 
    
         
            +
              f->error = malloc(strlen(error) + 1);
         
     | 
| 
      
 26 
     | 
    
         
            +
              strcpy(f->error, error);
         
     | 
| 
      
 27 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 28 
     | 
    
         
            +
            }
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            void free_stata(struct stata_file * f)
         
     | 
| 
      
 31 
     | 
    
         
            +
            {
         
     | 
| 
      
 32 
     | 
    
         
            +
              long i,j;
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
              free(f->filename);
         
     | 
| 
      
 35 
     | 
    
         
            +
              free(f->error);
         
     | 
| 
      
 36 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) free(f->varlist[i]);
         
     | 
| 
      
 37 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) free(f->fmtlist[i]);
         
     | 
| 
      
 38 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) free(f->lbllist[i]);
         
     | 
| 
      
 39 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) free(f->variable_labels[i]);
         
     | 
| 
      
 40 
     | 
    
         
            +
              free(f->typlist);
         
     | 
| 
      
 41 
     | 
    
         
            +
              free(f->varlist);
         
     | 
| 
      
 42 
     | 
    
         
            +
              free(f->srtlist);
         
     | 
| 
      
 43 
     | 
    
         
            +
              free(f->fmtlist);
         
     | 
| 
      
 44 
     | 
    
         
            +
              free(f->lbllist);
         
     | 
| 
      
 45 
     | 
    
         
            +
              free(f->variable_labels);
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              for (i = 0 ; i < f->nobs ; i++)
         
     | 
| 
      
 48 
     | 
    
         
            +
              {
         
     | 
| 
      
 49 
     | 
    
         
            +
                for (j = 0 ; j < f->nvar ; j++)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  if (f->obs[i].var[j].v_type == V_STR)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    free(f->obs[i].var[j].v_str);
         
     | 
| 
      
 52 
     | 
    
         
            +
                free(f->obs[i].var);
         
     | 
| 
      
 53 
     | 
    
         
            +
              }
         
     | 
| 
      
 54 
     | 
    
         
            +
              free(f->obs);
         
     | 
| 
      
 55 
     | 
    
         
            +
              
         
     | 
| 
      
 56 
     | 
    
         
            +
              for (i = 0 ; i < f->num_vlt ; i++)
         
     | 
| 
      
 57 
     | 
    
         
            +
              {
         
     | 
| 
      
 58 
     | 
    
         
            +
                free(f->vlt[i].off);
         
     | 
| 
      
 59 
     | 
    
         
            +
                free(f->vlt[i].val);
         
     | 
| 
      
 60 
     | 
    
         
            +
                free(f->vlt[i].txtbuf);
         
     | 
| 
      
 61 
     | 
    
         
            +
              }
         
     | 
| 
      
 62 
     | 
    
         
            +
              free(f->vlt);
         
     | 
| 
      
 63 
     | 
    
         
            +
              
         
     | 
| 
      
 64 
     | 
    
         
            +
              free(f);
         
     | 
| 
      
 65 
     | 
    
         
            +
            }
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            int main(int argc, char *argv[])
         
     | 
| 
      
 68 
     | 
    
         
            +
            {
         
     | 
| 
      
 69 
     | 
    
         
            +
              if (argc != 2) { fprintf(stderr, "usage:\n ./read [file]\n"); return(0); }
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              verbose = 1;
         
     | 
| 
      
 72 
     | 
    
         
            +
              
         
     | 
| 
      
 73 
     | 
    
         
            +
              char src_file[100];
         
     | 
| 
      
 74 
     | 
    
         
            +
              char dst_file[100];
         
     | 
| 
      
 75 
     | 
    
         
            +
              sprintf(src_file, "%s.dta", argv[1]);
         
     | 
| 
      
 76 
     | 
    
         
            +
              sprintf(dst_file, "%s_resave.dta", argv[1]);
         
     | 
| 
      
 77 
     | 
    
         
            +
              
         
     | 
| 
      
 78 
     | 
    
         
            +
              struct stata_file * f = read_stata_file(src_file);
         
     | 
| 
      
 79 
     | 
    
         
            +
              write_stata_file(dst_file, f);
         
     | 
| 
      
 80 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 81 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/Stata.h
    ADDED
    
    | 
         @@ -0,0 +1,72 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #ifndef STATA_H
         
     | 
| 
      
 3 
     | 
    
         
            +
            #define STATA_H
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include <inttypes.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            extern FILE * fp;
         
     | 
| 
      
 9 
     | 
    
         
            +
            extern int swap_endian_needed;
         
     | 
| 
      
 10 
     | 
    
         
            +
            extern int verbose;
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            enum stata_type {
         
     | 
| 
      
 13 
     | 
    
         
            +
              V_INVALID, V_STR, V_BYTE, V_INT, V_LONG, V_FLOAT, V_DOUBLE
         
     | 
| 
      
 14 
     | 
    
         
            +
            };
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            struct stata_var {
         
     | 
| 
      
 17 
     | 
    
         
            +
              enum stata_type v_type;
         
     | 
| 
      
 18 
     | 
    
         
            +
              union {
         
     | 
| 
      
 19 
     | 
    
         
            +
                char * v_str;
         
     | 
| 
      
 20 
     | 
    
         
            +
                int8_t v_byte;
         
     | 
| 
      
 21 
     | 
    
         
            +
                int16_t v_int;
         
     | 
| 
      
 22 
     | 
    
         
            +
                int32_t v_long;
         
     | 
| 
      
 23 
     | 
    
         
            +
                float v_float;
         
     | 
| 
      
 24 
     | 
    
         
            +
                double v_double;
         
     | 
| 
      
 25 
     | 
    
         
            +
              };
         
     | 
| 
      
 26 
     | 
    
         
            +
            };
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            struct stata_obs {
         
     | 
| 
      
 29 
     | 
    
         
            +
              struct stata_var * var;
         
     | 
| 
      
 30 
     | 
    
         
            +
            };
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            struct stata_vlt {
         
     | 
| 
      
 33 
     | 
    
         
            +
              char name[33];
         
     | 
| 
      
 34 
     | 
    
         
            +
              int32_t n;
         
     | 
| 
      
 35 
     | 
    
         
            +
              int32_t txtlen;
         
     | 
| 
      
 36 
     | 
    
         
            +
              int32_t * off;
         
     | 
| 
      
 37 
     | 
    
         
            +
              int32_t * val;
         
     | 
| 
      
 38 
     | 
    
         
            +
              char * txtbuf;
         
     | 
| 
      
 39 
     | 
    
         
            +
            };
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            struct stata_file {
         
     | 
| 
      
 42 
     | 
    
         
            +
              char * filename;
         
     | 
| 
      
 43 
     | 
    
         
            +
              
         
     | 
| 
      
 44 
     | 
    
         
            +
              int8_t ds_format;
         
     | 
| 
      
 45 
     | 
    
         
            +
              int8_t byteorder;
         
     | 
| 
      
 46 
     | 
    
         
            +
              int8_t filetype;
         
     | 
| 
      
 47 
     | 
    
         
            +
              int8_t unused;
         
     | 
| 
      
 48 
     | 
    
         
            +
              uint16_t nvar;
         
     | 
| 
      
 49 
     | 
    
         
            +
              uint32_t nobs;
         
     | 
| 
      
 50 
     | 
    
         
            +
              char data_label[81];
         
     | 
| 
      
 51 
     | 
    
         
            +
              char time_stamp[18];
         
     | 
| 
      
 52 
     | 
    
         
            +
              
         
     | 
| 
      
 53 
     | 
    
         
            +
              char * error;
         
     | 
| 
      
 54 
     | 
    
         
            +
              
         
     | 
| 
      
 55 
     | 
    
         
            +
              uint8_t * typlist;
         
     | 
| 
      
 56 
     | 
    
         
            +
              char ** varlist;
         
     | 
| 
      
 57 
     | 
    
         
            +
              uint16_t * srtlist;
         
     | 
| 
      
 58 
     | 
    
         
            +
              char ** fmtlist;
         
     | 
| 
      
 59 
     | 
    
         
            +
              char ** lbllist;
         
     | 
| 
      
 60 
     | 
    
         
            +
              char ** variable_labels;
         
     | 
| 
      
 61 
     | 
    
         
            +
              
         
     | 
| 
      
 62 
     | 
    
         
            +
              struct stata_obs * obs;
         
     | 
| 
      
 63 
     | 
    
         
            +
              
         
     | 
| 
      
 64 
     | 
    
         
            +
              int num_vlt;
         
     | 
| 
      
 65 
     | 
    
         
            +
              struct stata_vlt * vlt;
         
     | 
| 
      
 66 
     | 
    
         
            +
            };
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            extern char get_host_endian();
         
     | 
| 
      
 69 
     | 
    
         
            +
            extern int set_error(struct stata_file * f, const char * error);
         
     | 
| 
      
 70 
     | 
    
         
            +
            extern void free_stata(struct stata_file * f);
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            #endif
         
     | 
    
        data/ext/Stata.o
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/Stata.rb.c
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #include <ruby.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include "Stata.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            VALUE method_read(VALUE self, VALUE file);
         
     | 
| 
      
 6 
     | 
    
         
            +
            VALUE method_write(VALUE self, VALUE file);
         
     | 
| 
      
 7 
     | 
    
         
            +
            VALUE method_get_verbose(VALUE self);
         
     | 
| 
      
 8 
     | 
    
         
            +
            VALUE method_set_verbose(VALUE self, VALUE value);
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            void Init_Stata()
         
     | 
| 
      
 11 
     | 
    
         
            +
            {
         
     | 
| 
      
 12 
     | 
    
         
            +
              VALUE Stata_module = rb_define_module("Stata");
         
     | 
| 
      
 13 
     | 
    
         
            +
              rb_define_singleton_method(Stata_module, "read", method_read, 1);
         
     | 
| 
      
 14 
     | 
    
         
            +
              rb_define_singleton_method(Stata_module, "write", method_write, 2);
         
     | 
| 
      
 15 
     | 
    
         
            +
              rb_define_singleton_method(Stata_module, "verbose", method_get_verbose, 0);
         
     | 
| 
      
 16 
     | 
    
         
            +
              rb_define_singleton_method(Stata_module, "verbose=", method_set_verbose, 1);
         
     | 
| 
      
 17 
     | 
    
         
            +
            }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            VALUE method_get_verbose(VALUE self)
         
     | 
| 
      
 20 
     | 
    
         
            +
            {
         
     | 
| 
      
 21 
     | 
    
         
            +
              return verbose ? Qtrue : Qfalse;
         
     | 
| 
      
 22 
     | 
    
         
            +
            }
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            VALUE method_set_verbose(VALUE self, VALUE value)
         
     | 
| 
      
 25 
     | 
    
         
            +
            {
         
     | 
| 
      
 26 
     | 
    
         
            +
              verbose = RTEST(value);
         
     | 
| 
      
 27 
     | 
    
         
            +
              return method_get_verbose(self);
         
     | 
| 
      
 28 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/Stata.rb.o
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/Write.c
    ADDED
    
    | 
         @@ -0,0 +1,114 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #include "Write.h"
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include "Stata.h"
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <stdlib.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 7 
     | 
    
         
            +
            #include <math.h>
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            struct stata_file;
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            int write_stata_file(char * filename, struct stata_file * f)
         
     | 
| 
      
 12 
     | 
    
         
            +
            {
         
     | 
| 
      
 13 
     | 
    
         
            +
              if (verbose) printf("write file '%s'\n", filename);
         
     | 
| 
      
 14 
     | 
    
         
            +
              
         
     | 
| 
      
 15 
     | 
    
         
            +
              long i,j;
         
     | 
| 
      
 16 
     | 
    
         
            +
              
         
     | 
| 
      
 17 
     | 
    
         
            +
              if (f == NULL) return 0;
         
     | 
| 
      
 18 
     | 
    
         
            +
              
         
     | 
| 
      
 19 
     | 
    
         
            +
              fp = fopen(filename, "wb");
         
     | 
| 
      
 20 
     | 
    
         
            +
              if (fp == NULL) return set_error(f, "error opening file");
         
     | 
| 
      
 21 
     | 
    
         
            +
              
         
     | 
| 
      
 22 
     | 
    
         
            +
              if (f->nvar <= 0) return set_error(f, "nvar should be more then 0"); 
         
     | 
| 
      
 23 
     | 
    
         
            +
              if (f->nobs <= 0) return set_error(f, "nobs should be more then 0"); 
         
     | 
| 
      
 24 
     | 
    
         
            +
              
         
     | 
| 
      
 25 
     | 
    
         
            +
              /* 5.1 Headers */
         
     | 
| 
      
 26 
     | 
    
         
            +
              char header[4] = {0x72, get_host_endian(), 0x01, 0x00};
         
     | 
| 
      
 27 
     | 
    
         
            +
              if (fwrite(header, 4, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 28 
     | 
    
         
            +
              if (fwrite(&f->nvar, sizeof(f->nvar), 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 29 
     | 
    
         
            +
              if (fwrite(&f->nobs, sizeof(f->nobs), 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 30 
     | 
    
         
            +
              if (fwrite(f->data_label, sizeof(f->data_label), 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 31 
     | 
    
         
            +
              f->time_stamp[17] = 0;
         
     | 
| 
      
 32 
     | 
    
         
            +
              if (fwrite(f->time_stamp, sizeof(f->time_stamp), 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
              
         
     | 
| 
      
 35 
     | 
    
         
            +
              /* 5.2 Descriptors */
         
     | 
| 
      
 36 
     | 
    
         
            +
              if (fwrite(f->typlist, 1, f->nvar, fp) != f->nvar) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 37 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) if (fwrite(f->varlist[i], 33, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 38 
     | 
    
         
            +
              if (fwrite(f->srtlist, 2, f->nvar+1, fp) != (unsigned int)f->nvar+1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 39 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) if (fwrite(f->fmtlist[i], 49, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 40 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) if (fwrite(f->lbllist[i], 33, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 41 
     | 
    
         
            +
              
         
     | 
| 
      
 42 
     | 
    
         
            +
              
         
     | 
| 
      
 43 
     | 
    
         
            +
              /* 5.3 Variable Labels */
         
     | 
| 
      
 44 
     | 
    
         
            +
              for (i = 0 ; i < f->nvar ; i++) if (fwrite(f->variable_labels[i], 81, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 45 
     | 
    
         
            +
              
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              /* 5.4 Expansion Fields */
         
     | 
| 
      
 48 
     | 
    
         
            +
              char zeros[5] = {0,0,0,0,0};
         
     | 
| 
      
 49 
     | 
    
         
            +
              if (fwrite(zeros, 5, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 50 
     | 
    
         
            +
              
         
     | 
| 
      
 51 
     | 
    
         
            +
              
         
     | 
| 
      
 52 
     | 
    
         
            +
              /* 5.5 Data */
         
     | 
| 
      
 53 
     | 
    
         
            +
              /*printf("  write 5.5 Data (%dx%d)\n", f->nobs, f->nvar);*/
         
     | 
| 
      
 54 
     | 
    
         
            +
              for (j = 0 ; j < f->nobs ; j++)
         
     | 
| 
      
 55 
     | 
    
         
            +
              {
         
     | 
| 
      
 56 
     | 
    
         
            +
                for (i = 0 ; i < f->nvar ; i++)
         
     | 
| 
      
 57 
     | 
    
         
            +
                {
         
     | 
| 
      
 58 
     | 
    
         
            +
                  struct stata_var * var = &f->obs[j].var[i];
         
     | 
| 
      
 59 
     | 
    
         
            +
                  if (f->typlist[i] != 0 && f->typlist[i] < 245) { if (fwrite(var->v_str, f->typlist[i], 1, fp) != 1) return set_error(f, "fwrite to file failed"); }
         
     | 
| 
      
 60 
     | 
    
         
            +
                  else if (f->typlist[i] == 251) { if (fwrite(&var->v_byte, sizeof(var->v_byte), 1, fp) != 1) return set_error(f, "fwrite to file failed"); }
         
     | 
| 
      
 61 
     | 
    
         
            +
                  else if (f->typlist[i] == 252) { if (fwrite(&var->v_int, sizeof(var->v_int), 1, fp) != 1) return set_error(f, "fwrite to file failed"); }
         
     | 
| 
      
 62 
     | 
    
         
            +
                  else if (f->typlist[i] == 253) { if (fwrite(&var->v_long, sizeof(var->v_long), 1, fp) != 1) return set_error(f, "fwrite to file failed"); }
         
     | 
| 
      
 63 
     | 
    
         
            +
                  else if (f->typlist[i] == 254) { if (fwrite(&var->v_float, sizeof(var->v_float), 1, fp) != 1) return set_error(f, "fwrite to file failed"); }
         
     | 
| 
      
 64 
     | 
    
         
            +
                  else if (f->typlist[i] == 255) { if (fwrite(&var->v_double, sizeof(var->v_double), 1, fp) != 1) return set_error(f, "fwrite to file failed"); }
         
     | 
| 
      
 65 
     | 
    
         
            +
                }
         
     | 
| 
      
 66 
     | 
    
         
            +
              }
         
     | 
| 
      
 67 
     | 
    
         
            +
              
         
     | 
| 
      
 68 
     | 
    
         
            +
              
         
     | 
| 
      
 69 
     | 
    
         
            +
              /* 5.6 Value Labels */
         
     | 
| 
      
 70 
     | 
    
         
            +
              /*printf("  write 5.6 Value Labels (%d)\n", f->num_vlt);*/
         
     | 
| 
      
 71 
     | 
    
         
            +
              for (i = 0 ; i < f->num_vlt ; i++)
         
     | 
| 
      
 72 
     | 
    
         
            +
              {
         
     | 
| 
      
 73 
     | 
    
         
            +
                struct stata_vlt * vlt = &f->vlt[i];
         
     | 
| 
      
 74 
     | 
    
         
            +
                uint32_t len = 4 + 4 + 4*vlt->n + 4*vlt->n + vlt->txtlen;
         
     | 
| 
      
 75 
     | 
    
         
            +
                if (fwrite(&len, sizeof(len), 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 76 
     | 
    
         
            +
                if (fwrite(vlt->name, 33, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 77 
     | 
    
         
            +
                if (fwrite(zeros, 3, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 78 
     | 
    
         
            +
                if (fwrite(&vlt->n, sizeof(vlt->n), 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 79 
     | 
    
         
            +
                uint32_t txtlen = 0;
         
     | 
| 
      
 80 
     | 
    
         
            +
                for (j = 0 ; j < vlt->n ; j++)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  txtlen += (int)strlen(vlt->txtbuf + vlt->off[j]) + 1;
         
     | 
| 
      
 82 
     | 
    
         
            +
                
         
     | 
| 
      
 83 
     | 
    
         
            +
                if (fwrite(&txtlen, sizeof(txtlen), 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 84 
     | 
    
         
            +
                if (fwrite(vlt->off, sizeof(uint32_t), vlt->n, fp) != (unsigned int)vlt->n) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 85 
     | 
    
         
            +
                if (fwrite(vlt->val, sizeof(uint32_t), vlt->n, fp) != (unsigned int)vlt->n) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 86 
     | 
    
         
            +
                if (fwrite(vlt->txtbuf, txtlen, 1, fp) != 1) return set_error(f, "fwrite to file failed");
         
     | 
| 
      
 87 
     | 
    
         
            +
              }
         
     | 
| 
      
 88 
     | 
    
         
            +
              
         
     | 
| 
      
 89 
     | 
    
         
            +
              fclose(fp);
         
     | 
| 
      
 90 
     | 
    
         
            +
              return 0;
         
     | 
| 
      
 91 
     | 
    
         
            +
            }
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
    
        data/ext/Write.h
    ADDED
    
    
    
        data/ext/Write.o
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/Write.rb.c
    ADDED
    
    | 
         @@ -0,0 +1,259 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            #include <stdio.h>
         
     | 
| 
      
 3 
     | 
    
         
            +
            #include <string.h>
         
     | 
| 
      
 4 
     | 
    
         
            +
            #include <math.h>
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include <ruby.h>
         
     | 
| 
      
 6 
     | 
    
         
            +
            #include "Stata.h"
         
     | 
| 
      
 7 
     | 
    
         
            +
            #include "Write.h"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            #ifndef RUBY_19
         
     | 
| 
      
 10 
     | 
    
         
            +
            #ifndef RFLOAT_VALUE
         
     | 
| 
      
 11 
     | 
    
         
            +
            #define RFLOAT_VALUE(v) (RFLOAT(v)->value)
         
     | 
| 
      
 12 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 13 
     | 
    
         
            +
            #ifndef RARRAY_LEN
         
     | 
| 
      
 14 
     | 
    
         
            +
            #define RARRAY_LEN(v) (RARRAY(v)->len)
         
     | 
| 
      
 15 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 16 
     | 
    
         
            +
            #ifndef RARRAY_PTR
         
     | 
| 
      
 17 
     | 
    
         
            +
            #define RARRAY_PTR(v) (RARRAY(v)->ptr)
         
     | 
| 
      
 18 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 19 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            int populate_fields_from_ruby_index = 0;
         
     | 
| 
      
 22 
     | 
    
         
            +
            VALUE populate_fields_from_ruby(VALUE field, struct stata_file * f)
         
     | 
| 
      
 23 
     | 
    
         
            +
            {
         
     | 
| 
      
 24 
     | 
    
         
            +
              VALUE v;
         
     | 
| 
      
 25 
     | 
    
         
            +
              
         
     | 
| 
      
 26 
     | 
    
         
            +
              v = rb_hash_aref(field, rb_str_new2("type"));
         
     | 
| 
      
 27 
     | 
    
         
            +
              if (TYPE(v) != T_FIXNUM) rb_raise(rb_eArgError, "field type is not provided or is not a Fixnum");
         
     | 
| 
      
 28 
     | 
    
         
            +
              f->typlist[populate_fields_from_ruby_index] = NUM2INT(v);
         
     | 
| 
      
 29 
     | 
    
         
            +
              
         
     | 
| 
      
 30 
     | 
    
         
            +
              v = rb_hash_aref(field, rb_str_new2("name"));
         
     | 
| 
      
 31 
     | 
    
         
            +
              if (TYPE(v) != T_STRING) rb_raise(rb_eArgError, "field name is not provided or is not a Fixnum");
         
     | 
| 
      
 32 
     | 
    
         
            +
              f->varlist[populate_fields_from_ruby_index] = (char*)malloc(33);
         
     | 
| 
      
 33 
     | 
    
         
            +
              strncpy(f->varlist[populate_fields_from_ruby_index], rb_string_value_cstr(&v), 33);
         
     | 
| 
      
 34 
     | 
    
         
            +
              
         
     | 
| 
      
 35 
     | 
    
         
            +
              v = rb_hash_aref(field, rb_str_new2("sort"));
         
     | 
| 
      
 36 
     | 
    
         
            +
              if (TYPE(v) != T_FIXNUM) rb_raise(rb_eArgError, "field sort is not provided or is not a Fixnum");
         
     | 
| 
      
 37 
     | 
    
         
            +
              f->srtlist[populate_fields_from_ruby_index] = NUM2INT(v);
         
     | 
| 
      
 38 
     | 
    
         
            +
              
         
     | 
| 
      
 39 
     | 
    
         
            +
              v = rb_hash_aref(field, rb_str_new2("format"));
         
     | 
| 
      
 40 
     | 
    
         
            +
              if (TYPE(v) != T_STRING) rb_raise(rb_eArgError, "field format is not provided or is not a Fixnum");
         
     | 
| 
      
 41 
     | 
    
         
            +
              f->fmtlist[populate_fields_from_ruby_index] = (char*)malloc(49);
         
     | 
| 
      
 42 
     | 
    
         
            +
              strncpy(f->fmtlist[populate_fields_from_ruby_index], rb_string_value_cstr(&v), 49);
         
     | 
| 
      
 43 
     | 
    
         
            +
              
         
     | 
| 
      
 44 
     | 
    
         
            +
              v = rb_hash_aref(field, rb_str_new2("value_label"));
         
     | 
| 
      
 45 
     | 
    
         
            +
              if (TYPE(v) != T_STRING) rb_raise(rb_eArgError, "field value_label is not provided or is not a String");
         
     | 
| 
      
 46 
     | 
    
         
            +
              f->lbllist[populate_fields_from_ruby_index] = (char*)malloc(33);
         
     | 
| 
      
 47 
     | 
    
         
            +
              strncpy(f->lbllist[populate_fields_from_ruby_index], rb_string_value_cstr(&v), 33);
         
     | 
| 
      
 48 
     | 
    
         
            +
              
         
     | 
| 
      
 49 
     | 
    
         
            +
              v = rb_hash_aref(field, rb_str_new2("variable_label"));
         
     | 
| 
      
 50 
     | 
    
         
            +
              if (TYPE(v) != T_STRING) rb_raise(rb_eArgError, "field variable_label is not provided or is not a String");
         
     | 
| 
      
 51 
     | 
    
         
            +
              f->variable_labels[populate_fields_from_ruby_index] = (char*)malloc(81);
         
     | 
| 
      
 52 
     | 
    
         
            +
              strncpy(f->variable_labels[populate_fields_from_ruby_index], rb_string_value_cstr(&v), 81);
         
     | 
| 
      
 53 
     | 
    
         
            +
              
         
     | 
| 
      
 54 
     | 
    
         
            +
              populate_fields_from_ruby_index++;
         
     | 
| 
      
 55 
     | 
    
         
            +
            }
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            int populate_data_from_ruby_index = 0;
         
     | 
| 
      
 58 
     | 
    
         
            +
            VALUE populate_data_from_ruby(VALUE row, struct stata_file * f)
         
     | 
| 
      
 59 
     | 
    
         
            +
            {
         
     | 
| 
      
 60 
     | 
    
         
            +
              VALUE v;
         
     | 
| 
      
 61 
     | 
    
         
            +
              int j = 0;//, i = populate_data_from_ruby_index;
         
     | 
| 
      
 62 
     | 
    
         
            +
              for (j = 0 ; j < f->nvar ; j++)
         
     | 
| 
      
 63 
     | 
    
         
            +
              {
         
     | 
| 
      
 64 
     | 
    
         
            +
                v = rb_ary_entry(row, j);
         
     | 
| 
      
 65 
     | 
    
         
            +
                struct stata_var * var = &f->obs[populate_data_from_ruby_index].var[j];
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                if (f->typlist[j] == 255) var->v_type = V_DOUBLE;
         
     | 
| 
      
 68 
     | 
    
         
            +
                else if (f->typlist[j] == 254) var->v_type = V_FLOAT;
         
     | 
| 
      
 69 
     | 
    
         
            +
                else if (f->typlist[j] == 253) var->v_type = V_LONG;
         
     | 
| 
      
 70 
     | 
    
         
            +
                else if (f->typlist[j] == 252) var->v_type = V_INT;
         
     | 
| 
      
 71 
     | 
    
         
            +
                else if (f->typlist[j] == 251) var->v_type = V_BYTE;
         
     | 
| 
      
 72 
     | 
    
         
            +
                else if (f->typlist[j] <= 244) var->v_type = f->typlist[j];
         
     | 
| 
      
 73 
     | 
    
         
            +
                else rb_raise(rb_eArgError, "type is %d", f->typlist[j]);
         
     | 
| 
      
 74 
     | 
    
         
            +
                
         
     | 
| 
      
 75 
     | 
    
         
            +
                switch (TYPE(v)) {
         
     | 
| 
      
 76 
     | 
    
         
            +
                  case T_SYMBOL:
         
     | 
| 
      
 77 
     | 
    
         
            +
                    v = rb_str_new2(rb_id2name(SYM2ID(v)));
         
     | 
| 
      
 78 
     | 
    
         
            +
                    const char * symbol_name = RSTRING_PTR(v);
         
     | 
| 
      
 79 
     | 
    
         
            +
                    
         
     | 
| 
      
 80 
     | 
    
         
            +
                    int dot = 0;
         
     | 
| 
      
 81 
     | 
    
         
            +
                    if (strlen(symbol_name) == 5) dot = symbol_name[4] - 96;
         
     | 
| 
      
 82 
     | 
    
         
            +
                    if (dot < 0 || dot > 26) { rb_raise(rb_eArgError, "INVALID SYMBOL '%s'", symbol_name); continue; }
         
     | 
| 
      
 83 
     | 
    
         
            +
                    
         
     | 
| 
      
 84 
     | 
    
         
            +
                    if (f->typlist[j] == 255) var->v_double = pow(2, 1023) + dot*pow(2, 1011);
         
     | 
| 
      
 85 
     | 
    
         
            +
                    else if (f->typlist[j] == 254) var->v_float = (float)pow(2, 127) + dot*(float)pow(2, 115);
         
     | 
| 
      
 86 
     | 
    
         
            +
                    else if (f->typlist[j] == 253) var->v_long = 2147483621 + dot;
         
     | 
| 
      
 87 
     | 
    
         
            +
                    else if (f->typlist[j] == 252) var->v_int = 32741 + dot;
         
     | 
| 
      
 88 
     | 
    
         
            +
                    else if (f->typlist[j] == 251) var->v_byte = 101 + dot;
         
     | 
| 
      
 89 
     | 
    
         
            +
                    else rb_raise(rb_eArgError, "invalid typlist '%d' %d", f->typlist[j], TYPE(v));
         
     | 
| 
      
 90 
     | 
    
         
            +
                  break;
         
     | 
| 
      
 91 
     | 
    
         
            +
                  case T_BIGNUM:
         
     | 
| 
      
 92 
     | 
    
         
            +
                  case T_FIXNUM:
         
     | 
| 
      
 93 
     | 
    
         
            +
                  case T_FLOAT:
         
     | 
| 
      
 94 
     | 
    
         
            +
                    if (f->typlist[j] == 255) var->v_double = rb_num2dbl(v);
         
     | 
| 
      
 95 
     | 
    
         
            +
                    else if (f->typlist[j] == 254) var->v_float = (float)rb_num2dbl(v);
         
     | 
| 
      
 96 
     | 
    
         
            +
                    else if (f->typlist[j] == 253) var->v_long = (int32_t)FIX2LONG(v);
         
     | 
| 
      
 97 
     | 
    
         
            +
                    else if (f->typlist[j] == 252) var->v_int = FIX2LONG(v);
         
     | 
| 
      
 98 
     | 
    
         
            +
                    else if (f->typlist[j] == 251) var->v_byte = FIX2LONG(v);
         
     | 
| 
      
 99 
     | 
    
         
            +
                    else rb_raise(rb_eArgError, "invalid typlist '%d' %d %f", f->typlist[j], TYPE(v), RFLOAT_VALUE(v));
         
     | 
| 
      
 100 
     | 
    
         
            +
                  break;
         
     | 
| 
      
 101 
     | 
    
         
            +
                  case T_STRING:
         
     | 
| 
      
 102 
     | 
    
         
            +
                    var->v_type = f->typlist[j];
         
     | 
| 
      
 103 
     | 
    
         
            +
                    var->v_str = (char*)malloc(f->typlist[j]+1);
         
     | 
| 
      
 104 
     | 
    
         
            +
                    strncpy(var->v_str, RSTRING_PTR(v), f->typlist[j]+1);
         
     | 
| 
      
 105 
     | 
    
         
            +
                  break;
         
     | 
| 
      
 106 
     | 
    
         
            +
                  case T_NIL:
         
     | 
| 
      
 107 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "nil value submitted");
         
     | 
| 
      
 108 
     | 
    
         
            +
                  break;
         
     | 
| 
      
 109 
     | 
    
         
            +
                  default:
         
     | 
| 
      
 110 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "unsupported ruby type: %d", TYPE(v));
         
     | 
| 
      
 111 
     | 
    
         
            +
                  break;
         
     | 
| 
      
 112 
     | 
    
         
            +
                }
         
     | 
| 
      
 113 
     | 
    
         
            +
              }
         
     | 
| 
      
 114 
     | 
    
         
            +
              populate_data_from_ruby_index++;
         
     | 
| 
      
 115 
     | 
    
         
            +
            }
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            int populate_value_labels_from_ruby_index = 0;
         
     | 
| 
      
 118 
     | 
    
         
            +
            VALUE populate_value_labels_from_ruby(VALUE r_vlt, struct stata_file * f)
         
     | 
| 
      
 119 
     | 
    
         
            +
            {
         
     | 
| 
      
 120 
     | 
    
         
            +
              VALUE v;
         
     | 
| 
      
 121 
     | 
    
         
            +
              
         
     | 
| 
      
 122 
     | 
    
         
            +
              f->num_vlt++;
         
     | 
| 
      
 123 
     | 
    
         
            +
              f->vlt = (struct stata_vlt *)realloc(f->vlt, sizeof(struct stata_vlt)*f->num_vlt);
         
     | 
| 
      
 124 
     | 
    
         
            +
              struct stata_vlt * vlt = &f->vlt[f->num_vlt-1];
         
     | 
| 
      
 125 
     | 
    
         
            +
              
         
     | 
| 
      
 126 
     | 
    
         
            +
              if (TYPE(r_vlt) != T_HASH) rb_raise(rb_eArgError, "Value label table should be a Hash");
         
     | 
| 
      
 127 
     | 
    
         
            +
              
         
     | 
| 
      
 128 
     | 
    
         
            +
              v = rb_hash_aref(r_vlt, rb_str_new2("name"));
         
     | 
| 
      
 129 
     | 
    
         
            +
              if (TYPE(v) != T_STRING) rb_raise(rb_eArgError, "Value label table name isn't provided or isn't a String");
         
     | 
| 
      
 130 
     | 
    
         
            +
              strncpy(vlt->name, RSTRING_PTR(v), 33);
         
     | 
| 
      
 131 
     | 
    
         
            +
              
         
     | 
| 
      
 132 
     | 
    
         
            +
              v = rb_hash_aref(r_vlt, rb_str_new2("table"));
         
     | 
| 
      
 133 
     | 
    
         
            +
              if (TYPE(v) != T_ARRAY) rb_raise(rb_eArgError, "Value label table name isn't provided or isn't an Array");
         
     | 
| 
      
 134 
     | 
    
         
            +
              
         
     | 
| 
      
 135 
     | 
    
         
            +
              vlt->n = (int32_t)RARRAY_LEN(v);
         
     | 
| 
      
 136 
     | 
    
         
            +
              vlt->txtlen = 0;
         
     | 
| 
      
 137 
     | 
    
         
            +
              vlt->off = (uint32_t*)malloc(sizeof(uint32_t)*vlt->n);
         
     | 
| 
      
 138 
     | 
    
         
            +
              vlt->val = (uint32_t*)malloc(sizeof(uint32_t)*vlt->n);
         
     | 
| 
      
 139 
     | 
    
         
            +
              vlt->txtbuf = NULL;
         
     | 
| 
      
 140 
     | 
    
         
            +
              
         
     | 
| 
      
 141 
     | 
    
         
            +
              int i;
         
     | 
| 
      
 142 
     | 
    
         
            +
              for (i = 0 ; i < RARRAY_LEN(v) ; i++)
         
     | 
| 
      
 143 
     | 
    
         
            +
              {
         
     | 
| 
      
 144 
     | 
    
         
            +
                VALUE r = rb_ary_entry(v, i);
         
     | 
| 
      
 145 
     | 
    
         
            +
                if (TYPE(r) != T_ARRAY) rb_raise(rb_eArgError, "value label contains a row which isn't an Array");
         
     | 
| 
      
 146 
     | 
    
         
            +
                if (TYPE(rb_ary_entry(r, 0)) != T_FIXNUM) rb_raise(rb_eArgError, "value label contains a value which isn't a Fixnum");
         
     | 
| 
      
 147 
     | 
    
         
            +
                if (TYPE(rb_ary_entry(r, 1)) != T_STRING) rb_raise(rb_eArgError, "value label contains a label which isn't a String");
         
     | 
| 
      
 148 
     | 
    
         
            +
                char * txt = RSTRING_PTR(rb_ary_entry(r, 1));
         
     | 
| 
      
 149 
     | 
    
         
            +
                vlt->txtlen += (int32_t)strlen(txt)+1;
         
     | 
| 
      
 150 
     | 
    
         
            +
              }
         
     | 
| 
      
 151 
     | 
    
         
            +
              vlt->txtbuf = (char*)malloc(vlt->txtlen);
         
     | 
| 
      
 152 
     | 
    
         
            +
              
         
     | 
| 
      
 153 
     | 
    
         
            +
              vlt->txtlen = 0;
         
     | 
| 
      
 154 
     | 
    
         
            +
              for (i = 0 ; i < RARRAY_LEN(v) ; i++)
         
     | 
| 
      
 155 
     | 
    
         
            +
              {
         
     | 
| 
      
 156 
     | 
    
         
            +
                VALUE r = rb_ary_entry(v, i);
         
     | 
| 
      
 157 
     | 
    
         
            +
                vlt->val[i] = NUM2INT(rb_ary_entry(r, 0));
         
     | 
| 
      
 158 
     | 
    
         
            +
                char * txt = RSTRING_PTR(rb_ary_entry(r, 1));
         
     | 
| 
      
 159 
     | 
    
         
            +
                vlt->txtlen += (int32_t)strlen(txt)+1;
         
     | 
| 
      
 160 
     | 
    
         
            +
                
         
     | 
| 
      
 161 
     | 
    
         
            +
                vlt->off[i] = vlt->txtlen-((int32_t)strlen(txt)+1);
         
     | 
| 
      
 162 
     | 
    
         
            +
                memcpy(vlt->txtbuf+vlt->off[i], txt, strlen(txt)+1);
         
     | 
| 
      
 163 
     | 
    
         
            +
              }
         
     | 
| 
      
 164 
     | 
    
         
            +
              
         
     | 
| 
      
 165 
     | 
    
         
            +
              populate_value_labels_from_ruby_index++;
         
     | 
| 
      
 166 
     | 
    
         
            +
            }
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
            VALUE method_write(VALUE self, VALUE filename, VALUE data)
         
     | 
| 
      
 169 
     | 
    
         
            +
            {
         
     | 
| 
      
 170 
     | 
    
         
            +
              VALUE v;
         
     | 
| 
      
 171 
     | 
    
         
            +
              if (TYPE(data) != T_HASH) rb_raise(rb_eArgError, "Content to be written should be a hash");
         
     | 
| 
      
 172 
     | 
    
         
            +
              if (TYPE(filename) != T_STRING) rb_raise(rb_eArgError, "Filename for writing is not a string");
         
     | 
| 
      
 173 
     | 
    
         
            +
              
         
     | 
| 
      
 174 
     | 
    
         
            +
              if (rb_hash_aref(data, rb_str_new2("nvar")) == Qnil) rb_raise(rb_eArgError, "nvar is required");
         
     | 
| 
      
 175 
     | 
    
         
            +
              if (rb_hash_aref(data, rb_str_new2("nobs")) == Qnil) rb_raise(rb_eArgError, "nobs is required");
         
     | 
| 
      
 176 
     | 
    
         
            +
              if (rb_hash_aref(data, rb_str_new2("fields")) == Qnil) rb_raise(rb_eArgError, "no fields provided");
         
     | 
| 
      
 177 
     | 
    
         
            +
              if (rb_hash_aref(data, rb_str_new2("data")) == Qnil) rb_raise(rb_eArgError, "no data provided");
         
     | 
| 
      
 178 
     | 
    
         
            +
              
         
     | 
| 
      
 179 
     | 
    
         
            +
              struct stata_file * f = (struct stata_file *)malloc(sizeof(struct stata_file));
         
     | 
| 
      
 180 
     | 
    
         
            +
              if (f == NULL) rb_raise(rb_eArgError, "Could not allocate memory for the stata file");
         
     | 
| 
      
 181 
     | 
    
         
            +
              memset(f, 0, sizeof(struct stata_file));
         
     | 
| 
      
 182 
     | 
    
         
            +
              
         
     | 
| 
      
 183 
     | 
    
         
            +
              
         
     | 
| 
      
 184 
     | 
    
         
            +
              /* 5.1 Headers */
         
     | 
| 
      
 185 
     | 
    
         
            +
              v = rb_hash_aref(data, rb_str_new2("nvar"));
         
     | 
| 
      
 186 
     | 
    
         
            +
              if (TYPE(v) != T_FIXNUM) rb_raise(rb_eArgError, "nvar is not provided or is not a fixnum");
         
     | 
| 
      
 187 
     | 
    
         
            +
              f->nvar = NUM2UINT(v);
         
     | 
| 
      
 188 
     | 
    
         
            +
              
         
     | 
| 
      
 189 
     | 
    
         
            +
              v = rb_hash_aref(data, rb_str_new2("nobs"));
         
     | 
| 
      
 190 
     | 
    
         
            +
              if (TYPE(v) != T_FIXNUM) rb_raise(rb_eArgError, "nobs is not provided or is not a fixnum");
         
     | 
| 
      
 191 
     | 
    
         
            +
              f->nobs = NUM2UINT(v);
         
     | 
| 
      
 192 
     | 
    
         
            +
              
         
     | 
| 
      
 193 
     | 
    
         
            +
              v = rb_hash_aref(data, rb_str_new2("data_label"));
         
     | 
| 
      
 194 
     | 
    
         
            +
              if (TYPE(v) != T_STRING) rb_raise(rb_eArgError, "data_label is not provided or is not a string");
         
     | 
| 
      
 195 
     | 
    
         
            +
              strncpy(f->data_label, rb_string_value_cstr(&v), sizeof(f->data_label));
         
     | 
| 
      
 196 
     | 
    
         
            +
              
         
     | 
| 
      
 197 
     | 
    
         
            +
              v = rb_hash_aref(data, rb_str_new2("time_stamp"));
         
     | 
| 
      
 198 
     | 
    
         
            +
              if (TYPE(v) != T_STRING) rb_raise(rb_eArgError, "time_stamp is not provided or is not a string");
         
     | 
| 
      
 199 
     | 
    
         
            +
              strncpy(f->time_stamp, rb_string_value_cstr(&v), sizeof(f->time_stamp));
         
     | 
| 
      
 200 
     | 
    
         
            +
              
         
     | 
| 
      
 201 
     | 
    
         
            +
              
         
     | 
| 
      
 202 
     | 
    
         
            +
              /* 5.2 and 5.3, Descriptors and Variable Labels */
         
     | 
| 
      
 203 
     | 
    
         
            +
              f->typlist = (uint8_t *)malloc(f->nvar);
         
     | 
| 
      
 204 
     | 
    
         
            +
              if (f->typlist == NULL) rb_raise(rb_eRuntimeError, "Could not allocate more memory");
         
     | 
| 
      
 205 
     | 
    
         
            +
              f->varlist = (char **)malloc(sizeof(char *)*f->nvar);
         
     | 
| 
      
 206 
     | 
    
         
            +
              if (f->varlist == NULL) rb_raise(rb_eRuntimeError, "Could not allocate more memory");
         
     | 
| 
      
 207 
     | 
    
         
            +
              f->srtlist = (uint16_t *)malloc(sizeof(uint16_t)*(f->nvar+1));
         
     | 
| 
      
 208 
     | 
    
         
            +
              if (f->srtlist == NULL) rb_raise(rb_eRuntimeError, "Could not allocate more memory");
         
     | 
| 
      
 209 
     | 
    
         
            +
              f->fmtlist = (char **)malloc(sizeof(char *)*f->nvar);
         
     | 
| 
      
 210 
     | 
    
         
            +
              if (f->fmtlist == NULL) rb_raise(rb_eRuntimeError, "Could not allocate more memory");
         
     | 
| 
      
 211 
     | 
    
         
            +
              f->lbllist = (char **)malloc(sizeof(char *)*f->nvar);
         
     | 
| 
      
 212 
     | 
    
         
            +
              if (f->lbllist == NULL) rb_raise(rb_eRuntimeError, "Could not allocate more memory");
         
     | 
| 
      
 213 
     | 
    
         
            +
              f->variable_labels = (char **)malloc(sizeof(char *)*f->nvar);
         
     | 
| 
      
 214 
     | 
    
         
            +
              if (f->variable_labels == NULL) rb_raise(rb_eRuntimeError, "Could not allocate more memory");
         
     | 
| 
      
 215 
     | 
    
         
            +
              
         
     | 
| 
      
 216 
     | 
    
         
            +
              v = rb_hash_aref(data, rb_str_new2("fields"));
         
     | 
| 
      
 217 
     | 
    
         
            +
              if (TYPE(v) != T_ARRAY) rb_raise(rb_eArgError, "fields are not provided or are not an array");
         
     | 
| 
      
 218 
     | 
    
         
            +
              
         
     | 
| 
      
 219 
     | 
    
         
            +
              populate_fields_from_ruby_index = 0;
         
     | 
| 
      
 220 
     | 
    
         
            +
              rb_iterate(rb_each, v, populate_fields_from_ruby, (VALUE)f);
         
     | 
| 
      
 221 
     | 
    
         
            +
              
         
     | 
| 
      
 222 
     | 
    
         
            +
              
         
     | 
| 
      
 223 
     | 
    
         
            +
              /* 5.3 Expansion Fields - nothing comes from ruby */
         
     | 
| 
      
 224 
     | 
    
         
            +
              
         
     | 
| 
      
 225 
     | 
    
         
            +
              
         
     | 
| 
      
 226 
     | 
    
         
            +
              /* 5.4 Data */
         
     | 
| 
      
 227 
     | 
    
         
            +
              long i, j;
         
     | 
| 
      
 228 
     | 
    
         
            +
              f->obs = (struct stata_obs *)malloc(sizeof(struct stata_obs)*f->nobs);
         
     | 
| 
      
 229 
     | 
    
         
            +
              for (j = 0 ; j < f->nobs ; j++)
         
     | 
| 
      
 230 
     | 
    
         
            +
              {
         
     | 
| 
      
 231 
     | 
    
         
            +
                f->obs[j].var = (struct stata_var *)malloc(sizeof(struct stata_var)*f->nvar);
         
     | 
| 
      
 232 
     | 
    
         
            +
                for (i = 0 ; i < f->nvar ; i++)
         
     | 
| 
      
 233 
     | 
    
         
            +
                {
         
     | 
| 
      
 234 
     | 
    
         
            +
                  struct stata_var * var = &f->obs[j].var[i];
         
     | 
| 
      
 235 
     | 
    
         
            +
                  memset(var, 0, sizeof(struct stata_var));
         
     | 
| 
      
 236 
     | 
    
         
            +
                }
         
     | 
| 
      
 237 
     | 
    
         
            +
              }
         
     | 
| 
      
 238 
     | 
    
         
            +
              v = rb_hash_aref(data, rb_str_new2("data"));
         
     | 
| 
      
 239 
     | 
    
         
            +
              if (TYPE(v) != T_ARRAY) rb_raise(rb_eArgError, "data is not provided or is not an array");
         
     | 
| 
      
 240 
     | 
    
         
            +
              
         
     | 
| 
      
 241 
     | 
    
         
            +
              populate_data_from_ruby_index = 0;
         
     | 
| 
      
 242 
     | 
    
         
            +
              rb_iterate(rb_each, v, populate_data_from_ruby, (VALUE)f);
         
     | 
| 
      
 243 
     | 
    
         
            +
              
         
     | 
| 
      
 244 
     | 
    
         
            +
              
         
     | 
| 
      
 245 
     | 
    
         
            +
              /* 5.5 Value Label Tables */
         
     | 
| 
      
 246 
     | 
    
         
            +
              v = rb_hash_aref(data, rb_str_new2("value_labels"));
         
     | 
| 
      
 247 
     | 
    
         
            +
              if (TYPE(v) != T_ARRAY) rb_raise(rb_eArgError, "value labels are not provided or are not an array");
         
     | 
| 
      
 248 
     | 
    
         
            +
              
         
     | 
| 
      
 249 
     | 
    
         
            +
              populate_value_labels_from_ruby_index = 0;
         
     | 
| 
      
 250 
     | 
    
         
            +
              rb_iterate(rb_each, v, populate_value_labels_from_ruby, (VALUE)f);
         
     | 
| 
      
 251 
     | 
    
         
            +
              
         
     | 
| 
      
 252 
     | 
    
         
            +
              write_stata_file(RSTRING_PTR(filename), f);
         
     | 
| 
      
 253 
     | 
    
         
            +
              
         
     | 
| 
      
 254 
     | 
    
         
            +
              if (f->error) rb_raise(rb_eRuntimeError, "%s", f->error);
         
     | 
| 
      
 255 
     | 
    
         
            +
              
         
     | 
| 
      
 256 
     | 
    
         
            +
              free_stata(f);
         
     | 
| 
      
 257 
     | 
    
         
            +
              
         
     | 
| 
      
 258 
     | 
    
         
            +
              return INT2NUM(1);
         
     | 
| 
      
 259 
     | 
    
         
            +
            }
         
     | 
    
        data/ext/Write.rb.o
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/extconf.rb
    ADDED
    
    
    
        data/ext/stata_c_test
    ADDED
    
    | 
         Binary file 
     | 
    
        data/ext/test.rb
    ADDED
    
    | 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby -w
         
     | 
| 
      
 2 
     | 
    
         
            +
            #encoding:ASCII-8BIT
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            $LOAD_PATH << '.'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'Stata'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Stata.verbose = true
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            files = if ARGV.empty?
         
     | 
| 
      
 10 
     | 
    
         
            +
                      Dir.glob("test_file_*.dta")
         
     | 
| 
      
 11 
     | 
    
         
            +
                    else
         
     | 
| 
      
 12 
     | 
    
         
            +
                      ARGV
         
     | 
| 
      
 13 
     | 
    
         
            +
                    end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            if files.empty?
         
     | 
| 
      
 16 
     | 
    
         
            +
              puts "usage: #{$0} file1.dta [file2.dta ...]"
         
     | 
| 
      
 17 
     | 
    
         
            +
              exit(-1)
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            files.each do |original|
         
     | 
| 
      
 21 
     | 
    
         
            +
              if original =~ /_resave/
         
     | 
| 
      
 22 
     | 
    
         
            +
                puts "skipping #{original.inspect}\n\n"
         
     | 
| 
      
 23 
     | 
    
         
            +
                next
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              ext    = File.extname(original)
         
     | 
| 
      
 27 
     | 
    
         
            +
              base   = original[0..-(ext.length+1)]
         
     | 
| 
      
 28 
     | 
    
         
            +
              resave = "#{base}_resave#{ext}"
         
     | 
| 
      
 29 
     | 
    
         
            +
              
         
     | 
| 
      
 30 
     | 
    
         
            +
              s1 = Stata.read(original)
         
     | 
| 
      
 31 
     | 
    
         
            +
              Stata.write(resave, s1)
         
     | 
| 
      
 32 
     | 
    
         
            +
              
         
     | 
| 
      
 33 
     | 
    
         
            +
              s2 = Stata.read(resave)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              ['data', 'fields', 'value_labels'].each do |f|
         
     | 
| 
      
 36 
     | 
    
         
            +
                if (s1[f] != s2[f])
         
     | 
| 
      
 37 
     | 
    
         
            +
                  puts "ERROR '#{file}' #{f} did not read/write the same!"
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              puts "\n"
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,99 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: stata
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 5 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 6 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 9 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
      
 10 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 11 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 12 
     | 
    
         
            +
            - Kevin Branigan
         
     | 
| 
      
 13 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 14 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 15 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            date: 2011-01-18 00:00:00 +00:00
         
     | 
| 
      
 18 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 19 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 20 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 21 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 22 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 23 
     | 
    
         
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 24 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 25 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 26 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 27 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 28 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 29 
     | 
    
         
            +
                    - 2
         
     | 
| 
      
 30 
     | 
    
         
            +
                    - 4
         
     | 
| 
      
 31 
     | 
    
         
            +
                    version: "2.4"
         
     | 
| 
      
 32 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 33 
     | 
    
         
            +
              version_requirements: *id001
         
     | 
| 
      
 34 
     | 
    
         
            +
            description: 
         
     | 
| 
      
 35 
     | 
    
         
            +
            email: 
         
     | 
| 
      
 36 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            extensions: 
         
     | 
| 
      
 39 
     | 
    
         
            +
            - ext/extconf.rb
         
     | 
| 
      
 40 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 43 
     | 
    
         
            +
            - ext/extconf.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - ext/Makefile
         
     | 
| 
      
 45 
     | 
    
         
            +
            - ext/Makefile_c
         
     | 
| 
      
 46 
     | 
    
         
            +
            - ext/Read.c
         
     | 
| 
      
 47 
     | 
    
         
            +
            - ext/Read.h
         
     | 
| 
      
 48 
     | 
    
         
            +
            - ext/Read.o
         
     | 
| 
      
 49 
     | 
    
         
            +
            - ext/Read.rb.c
         
     | 
| 
      
 50 
     | 
    
         
            +
            - ext/Read.rb.o
         
     | 
| 
      
 51 
     | 
    
         
            +
            - ext/Stata.bundle
         
     | 
| 
      
 52 
     | 
    
         
            +
            - ext/Stata.c
         
     | 
| 
      
 53 
     | 
    
         
            +
            - ext/Stata.h
         
     | 
| 
      
 54 
     | 
    
         
            +
            - ext/Stata.o
         
     | 
| 
      
 55 
     | 
    
         
            +
            - ext/Stata.rb.c
         
     | 
| 
      
 56 
     | 
    
         
            +
            - ext/Stata.rb.o
         
     | 
| 
      
 57 
     | 
    
         
            +
            - ext/stata_c_test
         
     | 
| 
      
 58 
     | 
    
         
            +
            - ext/test.rb
         
     | 
| 
      
 59 
     | 
    
         
            +
            - ext/Write.c
         
     | 
| 
      
 60 
     | 
    
         
            +
            - ext/Write.h
         
     | 
| 
      
 61 
     | 
    
         
            +
            - ext/Write.o
         
     | 
| 
      
 62 
     | 
    
         
            +
            - ext/Write.rb.c
         
     | 
| 
      
 63 
     | 
    
         
            +
            - ext/Write.rb.o
         
     | 
| 
      
 64 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 65 
     | 
    
         
            +
            - README
         
     | 
| 
      
 66 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 67 
     | 
    
         
            +
            homepage: http://github.com/unspace/stata
         
     | 
| 
      
 68 
     | 
    
         
            +
            licenses: 
         
     | 
| 
      
 69 
     | 
    
         
            +
            - MIT
         
     | 
| 
      
 70 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 71 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 74 
     | 
    
         
            +
            - ext
         
     | 
| 
      
 75 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 76 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 77 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 78 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 79 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 80 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 81 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 82 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 83 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 84 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 85 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 86 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 87 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 88 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 89 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 90 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 91 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 94 
     | 
    
         
            +
            rubygems_version: 1.3.7
         
     | 
| 
      
 95 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 96 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 97 
     | 
    
         
            +
            summary: Read and write support for the Stata binary format
         
     | 
| 
      
 98 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     |