KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jruby > RubyArgsFile


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
15  * Copyright (C) 2002-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
16  * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
17  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
18  * Copyright (C) 2007 Ola Bini <ola@ologix.com>
19  *
20  * Alternatively, the contents of this file may be used under the terms of
21  * either of the GNU General Public License Version 2 or later (the "GPL"),
22  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23  * in which case the provisions of the GPL or the LGPL are applicable instead
24  * of those above. If you wish to allow use of your version of this file only
25  * under the terms of either the GPL or the LGPL, and not to allow others to
26  * use your version of this file under the terms of the CPL, indicate your
27  * decision by deleting the provisions above and replace them with the notice
28  * and other provisions required by the GPL or the LGPL. If you do not delete
29  * the provisions above, a recipient may use your version of this file under
30  * the terms of any one of the CPL, the GPL or the LGPL.
31  ***** END LICENSE BLOCK *****/

32 package org.jruby;
33
34 import org.jruby.runtime.Block;
35 import org.jruby.runtime.CallbackFactory;
36 import org.jruby.runtime.ThreadContext;
37 import org.jruby.runtime.builtin.IRubyObject;
38
39 public class RubyArgsFile extends RubyObject {
40
41     public RubyArgsFile(Ruby runtime) {
42         super(runtime, runtime.getObject());
43     }
44
45     private IRubyObject currentFile = null;
46     private int currentLineNumber;
47     
48     public void setCurrentLineNumber(int newLineNumber) {
49         this.currentLineNumber = newLineNumber;
50     }
51     
52     public void initArgsFile() {
53         extendObject(getRuntime().getModule("Enumerable"));
54         
55         getRuntime().defineReadonlyVariable("$<", this);
56         getRuntime().defineGlobalConstant("ARGF", this);
57         
58         CallbackFactory callbackFactory = getRuntime().callbackFactory(RubyArgsFile.class);
59         getMetaClass().defineMethod("each", callbackFactory.getOptMethod("each_line"));
60         getMetaClass().defineMethod("each_line", callbackFactory.getOptMethod("each_line"));
61
62         getMetaClass().defineFastMethod("filename", callbackFactory.getFastMethod("filename"));
63         getMetaClass().defineFastMethod("gets", callbackFactory.getFastOptMethod("gets"));
64         getMetaClass().defineFastMethod("readline", callbackFactory.getFastOptMethod("readline"));
65         getMetaClass().defineFastMethod("readlines", callbackFactory.getFastOptMethod("readlines"));
66         
67         getMetaClass().defineFastMethod("to_a", callbackFactory.getFastOptMethod("readlines"));
68         getMetaClass().defineFastMethod("to_s", callbackFactory.getFastMethod("to_s"));
69
70         getRuntime().defineReadonlyVariable("$FILENAME", getRuntime().newString("-"));
71
72         // This is ugly. nextArgsFile both checks existence of another
73
// file and the setup of any files. On top of that it handles
74
// the logic for figuring out stdin versus a list of files.
75
// I hacked this to make a null currentFile indicate that things
76
// have not been set up yet. This seems fragile, but it at least
77
// it passes tests now.
78
// currentFile = (RubyIO) getRuntime().getGlobalVariables().get("$stdin");
79
}
80
81     protected boolean nextArgsFile() {
82         RubyArray args = (RubyArray)getRuntime().getGlobalVariables().get("$*");
83
84         if (args.getLength() == 0) {
85             if (currentFile == null) {
86                 currentFile = getRuntime().getGlobalVariables().get("$stdin");
87                 ((RubyString) getRuntime().getGlobalVariables().get("$FILENAME")).setValue(new StringBuffer JavaDoc("-"));
88                 currentLineNumber = 0;
89                 return true;
90             }
91
92             return false;
93         }
94
95         String JavaDoc filename = ((RubyString) args.shift()).toString();
96         ((RubyString) getRuntime().getGlobalVariables().get("$FILENAME")).setValue(new StringBuffer JavaDoc(filename));
97
98         if (filename.equals("-")) {
99             currentFile = getRuntime().getGlobalVariables().get("$stdin");
100         } else {
101             currentFile = new RubyFile(getRuntime(), filename);
102         }
103
104         return true;
105     }
106     
107     public IRubyObject internalGets(IRubyObject[] args) {
108         if (currentFile == null && !nextArgsFile()) {
109             return getRuntime().getNil();
110         }
111         
112         ThreadContext context = getRuntime().getCurrentContext();
113         
114         IRubyObject line = currentFile.callMethod(context, "gets", args);
115         
116         while (line instanceof RubyNil) {
117             currentFile.callMethod(context, "close");
118             if (! nextArgsFile()) {
119                 currentFile = null;
120                 return line;
121             }
122             line = currentFile.callMethod(context, "gets", args);
123         }
124         
125         currentLineNumber++;
126         getRuntime().getGlobalVariables().set("$.", getRuntime().newFixnum(currentLineNumber));
127         
128         return line;
129     }
130     
131     // ARGF methods
132

133     /** Read a line.
134      *
135      */

136     public IRubyObject gets(IRubyObject[] args) {
137         IRubyObject result = internalGets(args);
138
139         if (!result.isNil()) {
140             getRuntime().getCurrentContext().setLastline(result);
141         }
142
143         return result;
144     }
145     
146     /** Read a line.
147      *
148      */

149     public IRubyObject readline(IRubyObject[] args) {
150         IRubyObject line = gets(args);
151
152         if (line.isNil()) {
153             throw getRuntime().newEOFError();
154         }
155         
156         return line;
157     }
158
159     public RubyArray readlines(IRubyObject[] args) {
160         IRubyObject[] separatorArgument;
161         if (args.length > 0) {
162             if (!args[0].isKindOf(getRuntime().getNilClass()) &&
163                 !args[0].isKindOf(getRuntime().getString())) {
164                 throw getRuntime().newTypeError(args[0],
165                         getRuntime().getString());
166             }
167             separatorArgument = new IRubyObject[] { args[0] };
168         } else {
169             separatorArgument = IRubyObject.NULL_ARRAY;
170         }
171
172         RubyArray result = getRuntime().newArray();
173         IRubyObject line;
174         while (! (line = internalGets(separatorArgument)).isNil()) {
175             result.append(line);
176         }
177         return result;
178     }
179     
180
181     /** Invoke a block for each line.
182      *
183      */

184     public IRubyObject each_line(IRubyObject[] args, Block block) {
185         IRubyObject nextLine = internalGets(args);
186         
187         while (!nextLine.isNil()) {
188             getRuntime().getCurrentContext().yield(nextLine, block);
189             nextLine = internalGets(args);
190         }
191         
192         return this;
193     }
194     
195     public RubyString filename() {
196         return (RubyString)getRuntime().getGlobalVariables().get("$FILENAME");
197     }
198
199     public IRubyObject to_s() {
200         return getRuntime().newString("ARGF");
201     }
202 }
203
Popular Tags