From f9c272157345f1fd4b8608242fe22bd3c718ddf6 Mon Sep 17 00:00:00 2001 From: shugo Date: Tue, 2 Nov 2004 05:51:31 +0000 Subject: [PATCH] added new option -s. --- README.ja | 3 +- eruby.1 | 11 ++-- eruby.h | 6 +- eruby_lib.c | 86 ++++---------------------- eruby_main.c | 172 +++++++++++++++++++++++++++++++++++++++++---------- 5 files changed, 162 insertions(+), 116 deletions(-) diff --git a/README.ja b/README.ja index 2df3347..165e1cc 100644 --- a/README.ja +++ b/README.ja @@ -5,8 +5,7 @@ == eRubyとは? eRubyはRubyのコードが埋めこまれたテキストファイルを解釈実行します。 -たとえば、eRubyを使えば、HTMLにRubyのコードをHTMLファイルに埋めこむ -ことができます。 +たとえば、eRubyを使えば、HTMLにRubyのコードを埋めこむことができます。 == 要求される環境 diff --git a/eruby.1 b/eruby.1 index 204702c..5221db8 100644 --- a/eruby.1 +++ b/eruby.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! it was generated by rd2 -.TH eruby 1 "September 2000" +.TH eruby 1 "November 2004" .SH NAME .PP eruby \- Embedded Ruby Language @@ -10,13 +10,15 @@ eruby [options] [inputfile] .PP eruby interprets a Ruby code embedded text file. For example, eruby enables you to embed a Ruby code to a HTML file. +.PP A Ruby block starts with `<%' and ends with `%>'. eRuby replaces the block with its output. +.PP If `<%' is followed by `=', eRuby replaces the block with a value of the block. +.PP If `<%' is followed by `#', the block is ignored as a comment. .SH OPTIONS -.PP .TP .fi .B @@ -36,8 +38,7 @@ specifies runtime mode \& f: filter mode \& c: CGI mode \& n: NPH\-CGI mode -.fi -.TP +.fi.TP .fi .B \-C charset @@ -55,7 +56,7 @@ enables verbose mode .TP .fi .B -\-\-version +\-\-version print version information and exit .SH AUTHOR .PP diff --git a/eruby.h b/eruby.h index 1015b47..461b674 100644 --- a/eruby.h +++ b/eruby.h @@ -1,5 +1,5 @@ /* - * $Id: eruby.h,v 1.31 2003/12/23 15:11:54 shugo Exp $ + * $Id$ * Copyright (C) 2000 ZetaBITS, Inc. * Copyright (C) 2000 Information-technology Promotion Agency, Japan */ @@ -7,7 +7,7 @@ #ifndef ERUBY_H #define ERUBY_H -#define ERUBY_VERSION "1.0.5" +#define ERUBY_VERSION "1.0.6" #define ERUBY_MIME_TYPE "application/x-httpd-eruby" @@ -28,6 +28,7 @@ enum eruby_mode { extern char *eruby_filename; extern int eruby_mode; extern int eruby_noheader; +extern int eruby_sync; extern VALUE eruby_charset; extern VALUE eruby_default_charset; #define ERUBY_CHARSET RSTRING(eruby_charset)->ptr @@ -35,6 +36,7 @@ extern VALUE eruby_default_charset; const char *eruby_version(); int eruby_parse_options(int argc, char **argv, int *optind); VALUE eruby_compiler_new(); +VALUE eruby_compiler_set_sourcefile(VALUE self, VALUE filename); VALUE eruby_compiler_compile_file(VALUE self, VALUE file); VALUE eruby_compiler_compile_string(VALUE self, VALUE s); VALUE eruby_load(char *filename, int wrap, int *state); diff --git a/eruby_lib.c b/eruby_lib.c index 08e5b99..2437fc4 100644 --- a/eruby_lib.c +++ b/eruby_lib.c @@ -1,5 +1,5 @@ /* - * $Id: eruby_lib.c,v 1.19 2003/07/29 03:42:56 shugo Exp $ + * $Id$ * Copyright (C) 2000 ZetaBITS, Inc. * Copyright (C) 2000 Information-technology Promotion Agency, Japan * Copyright (C) 2000 Shugo Maeda @@ -48,6 +48,7 @@ static VALUE eERubyCompileError; char *eruby_filename = NULL; int eruby_mode = MODE_UNKNOWN; int eruby_noheader = 0; +int eruby_sync = 0; VALUE eruby_charset; VALUE eruby_default_charset; @@ -82,6 +83,7 @@ usage: %s [switches] [inputfile]\n\n\ n: NPH-CGI mode\n\ -C [charset] specifies charset parameter for Content-Type\n\ -n, --noheader disables CGI header output\n\ + -s, --sync sync output\n\ -v, --verbose enables verbose mode\n\ --version print version information and exit\n\ \n", progname); @@ -173,6 +175,10 @@ int eruby_parse_options(int argc, char **argv, int *optind) eruby_noheader = 1; s++; goto again; + case 's': + eruby_sync = 1; + s++; + goto again; case '\0': break; case 'h': @@ -192,6 +198,12 @@ int eruby_parse_options(int argc, char **argv, int *optind) s += 8; goto again; } + else if (strncmp(s, "sync", 4) == 0 + && (s[4] == '\0' || isspace(s[4]))) { + eruby_sync = 1; + s += 4; + goto again; + } else if (strncmp(s, "version", 7) == 0 && (s[7] == '\0' || isspace(s[7]))) { show_version(); @@ -632,78 +644,6 @@ VALUE eruby_compiler_compile_file(VALUE self, VALUE file) return eruby_compile(compiler); } -static VALUE file_open(VALUE filename) -{ - return rb_file_open((char *) filename, "r"); -} - -typedef struct compile_arg { - VALUE compiler; - VALUE input; -} compile_arg_t; - -static VALUE eruby_compile_file(VALUE arg) -{ - return eruby_compiler_compile_file(((compile_arg_t *) arg)->compiler, - ((compile_arg_t *) arg)->input); -} - -typedef struct eval_arg { - VALUE src; - VALUE filename; -} eval_arg_t; - -static VALUE eval_string(VALUE arg) -{ - return rb_funcall(ruby_top_self, rb_intern("eval"), 3, - ((eval_arg_t *) arg)->src, - Qnil, - ((eval_arg_t *) arg)->filename); -} - -VALUE eruby_load(char *filename, int wrap, int *state) -{ - VALUE compiler; - VALUE code; - VALUE f; - VALUE vfilename = rb_str_new2(filename); - compile_arg_t carg; - eval_arg_t earg; - int status; - - if (strcmp(filename, "-") == 0) { - f = rb_stdin; - } - else { - f = rb_protect(file_open, (VALUE) filename, &status); - if (status) { - if (state) *state = status; - return Qnil; - } - } - compiler = eruby_compiler_new(); - eruby_compiler_set_sourcefile(compiler, vfilename); - carg.compiler = compiler; - carg.input = f; - code = rb_protect(eruby_compile_file, (VALUE) &carg, &status); - if (status) { - if (state) *state = status; - return Qnil; - } - if (wrap) { - rb_eval_string_wrap(STR2CSTR(code), &status); - } - else { - earg.src = code; - earg.filename = vfilename; - rb_protect(eval_string, (VALUE) &earg, &status); - } - if (state) *state = status; - if (f != rb_stdin) - rb_io_close(f); - return code; -} - static VALUE noheader_getter() { return eruby_noheader ? Qtrue : Qfalse; diff --git a/eruby_main.c b/eruby_main.c index b4652bb..cf2d830 100644 --- a/eruby_main.c +++ b/eruby_main.c @@ -42,6 +42,7 @@ EXTERN VALUE rb_stdout; EXTERN VALUE rb_defout; #endif EXTERN VALUE rb_load_path; +EXTERN VALUE ruby_top_self; /* copied from eval.c */ #define TAG_RETURN 0x1 @@ -453,18 +454,6 @@ static void init() #endif if (eruby_mode == MODE_CGI || eruby_mode == MODE_NPHCGI) rb_set_safe_level(1); - -#if RUBY_VERSION_CODE >= 180 - rb_io_binmode(rb_stdout); /* for mswin32 */ - rb_stdout = rb_str_new("", 0); - rb_define_singleton_method(rb_stdout, "write", defout_write, 1); - rb_define_singleton_method(rb_stdout, "cancel", defout_cancel, 0); -#else - rb_defout = rb_str_new("", 0); - rb_io_binmode(rb_stdout); /* for mswin32 */ - rb_define_singleton_method(rb_defout, "write", defout_write, 1); - rb_define_singleton_method(rb_defout, "cancel", defout_cancel, 0); -#endif eruby_init(); } @@ -546,17 +535,8 @@ static void proc_args(int argc, char **argv) } } -static void run() +static void error(int state, VALUE code) { - VALUE stack_start; - VALUE code; - int state; - char *out; - int nout; - void Init_stack _((VALUE*)); - - Init_stack(&stack_start); - code = eruby_load(eruby_filename, 0, &state); if (state && !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) { if (RTEST(ruby_debug) && (eruby_mode == MODE_CGI || eruby_mode == MODE_NPHCGI)) { @@ -568,28 +548,152 @@ static void run() eruby_exit(1); } } - if (eruby_mode == MODE_FILTER && (RTEST(ruby_debug) || RTEST(ruby_verbose))) { - print_generated_code(stderr, code, 0); - } - rb_exec_end_proc(); -#if RUBY_VERSION_CODE >= 180 - out = RSTRING(rb_stdout)->ptr; - nout = RSTRING(rb_stdout)->len; -#else - out = RSTRING(rb_defout)->ptr; - nout = RSTRING(rb_defout)->len; -#endif +} + +static void print_headers(int length) +{ if (!eruby_noheader && (eruby_mode == MODE_CGI || eruby_mode == MODE_NPHCGI)) { if (eruby_mode == MODE_NPHCGI) print_http_headers(); printf("Content-Type: text/html; charset=%s\r\n", ERUBY_CHARSET); - printf("Content-Length: %d\r\n", nout); + if (length >= 0) { + printf("Content-Length: %d\r\n", length); + } printf("\r\n"); } +} + +static void replace_stdout() +{ +#if RUBY_VERSION_CODE >= 180 + rb_io_binmode(rb_stdout); /* for mswin32 */ + rb_stdout = rb_str_new("", 0); + rb_define_singleton_method(rb_stdout, "write", defout_write, 1); + rb_define_singleton_method(rb_stdout, "cancel", defout_cancel, 0); +#else + rb_defout = rb_str_new("", 0); + rb_io_binmode(rb_stdout); /* for mswin32 */ + rb_define_singleton_method(rb_defout, "write", defout_write, 1); + rb_define_singleton_method(rb_defout, "cancel", defout_cancel, 0); +#endif +} + +static void flush_buffer() +{ + char *out; + int nout; + +#if RUBY_VERSION_CODE >= 180 + out = RSTRING(rb_stdout)->ptr; + nout = RSTRING(rb_stdout)->len; +#else + out = RSTRING(rb_defout)->ptr; + nout = RSTRING(rb_defout)->len; +#endif + print_headers(nout); fwrite(out, nout, 1, stdout); fflush(stdout); +} + +static VALUE file_open(VALUE filename) +{ + return rb_file_open((char *) filename, "r"); +} + +typedef struct compile_arg { + VALUE compiler; + VALUE input; +} compile_arg_t; + +static VALUE eruby_compile_file(VALUE arg) +{ + return eruby_compiler_compile_file(((compile_arg_t *) arg)->compiler, + ((compile_arg_t *) arg)->input); +} + +static VALUE compile(char *filename) +{ + VALUE compiler; + VALUE code; + VALUE f; + VALUE vfilename = rb_str_new2(filename); + compile_arg_t carg; + int status; + + if (strcmp(filename, "-") == 0) { + f = rb_stdin; + } + else { + f = rb_protect(file_open, (VALUE) filename, &status); + if (status) { + error(status, Qnil); + } + } + compiler = eruby_compiler_new(); + eruby_compiler_set_sourcefile(compiler, vfilename); + carg.compiler = compiler; + carg.input = f; + code = rb_protect(eruby_compile_file, (VALUE) &carg, &status); + if (status) { + error(status, Qnil); + } + if (f != rb_stdin) + rb_io_close(f); + return code; +} + +typedef struct eval_arg { + VALUE src; + VALUE filename; +} eval_arg_t; + +static VALUE eval_string(VALUE arg) +{ + return rb_funcall(ruby_top_self, rb_intern("eval"), 3, + ((eval_arg_t *) arg)->src, + Qnil, + ((eval_arg_t *) arg)->filename); +} + +static VALUE eval(VALUE code, char *filename) +{ + int status; + eval_arg_t earg; + + earg.src = code; + earg.filename = rb_str_new2(filename); + rb_protect(eval_string, (VALUE) &earg, &status); + if (status) { + error(status, code); + } + return code; +} + +static void run() +{ + VALUE stack_start; + VALUE code; + void Init_stack _((VALUE*)); + + Init_stack(&stack_start); + code = compile(eruby_filename); + if (eruby_sync) { + print_headers(-1); + } + else { + replace_stdout(); + } + code = eval(code, eruby_filename); + if (eruby_mode == MODE_FILTER && + (RTEST(ruby_debug) || RTEST(ruby_verbose))) { + print_generated_code(stderr, code, 0); + } + rb_exec_end_proc(); + if (!eruby_sync) { + flush_buffer(); + } ruby_finalize(); }