1
+ <?php
2
+ // This file is part of Moodle - https://moodle.org
3
+ //
4
+ // Moodle is free software: you can redistribute it and/or modify
5
+ // it under the terms of the GNU General Public License as published by
6
+ // the Free Software Foundation, either version 3 of the License, or
7
+ // (at your option) any later version.
8
+ //
9
+ // Moodle is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU General Public License for more details.
13
+ //
14
+ // You should have received a copy of the GNU General Public License
15
+ // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ /**
18
+ * NOTICE OF COPYRIGHT
19
+ *
20
+ * Online Judge for Moodle
21
+ * https://github.com/hit-moodle/moodle-local_onlinejudge
22
+ *
23
+ * Copyright (C) 2009 onwards
24
+ * Sun Zhigang http://sunner.cn
25
+ * Andrew Naguib <andrew at fci helwan edu eg>
26
+ * This program is free software; you can redistribute it and/or modify
27
+ * it under the terms of the GNU General Public License as published by
28
+ * the Free Software Foundation; either version 3 of the License, or
29
+ * (at your option) any later version.
30
+ *
31
+ * This program is distributed in the hope that it will be useful,
32
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34
+ * GNU General Public License for more details:
35
+ *
36
+ * http://www.gnu.org/copyleft/gpl.html
37
+ */
38
+
39
+ /**
40
+ * Judge base class
41
+ *
42
+ * @package local_onlinejudge
43
+ * @copyright 2011 Sun Zhigang (http://sunner.cn)
44
+ * @author Sun Zhigang
45
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46
+ */
47
+
48
+ namespace local_onlinejudge \judge ;
49
+
50
+ defined ('MOODLE_INTERNAL ' ) || die ();
51
+
52
+ class base {
53
+
54
+ // object of the task
55
+ protected $ task ;
56
+
57
+ // language id without judge id
58
+ protected $ language ;
59
+
60
+ function __construct ($ task ) {
61
+ $ this ->task = $ task ;
62
+ $ this ->language = substr ($ this ->task ->language , 0 , strpos ($ this ->task ->language , '- ' ));
63
+ }
64
+
65
+ /**
66
+ * Return an array of programming languages supported by this judge
67
+ *
68
+ * The array key must be the language's ID, such as c_sandbox, python_ideone.
69
+ * The array value must be a human-readable name of the language, such as 'C (local)', 'Python (ideone.com)'
70
+ */
71
+ static function get_languages () {
72
+ return array ();
73
+ }
74
+
75
+ /**
76
+ * Put options into task
77
+ *
78
+ * @param object options
79
+ * @return throw exceptions on error
80
+ */
81
+ static function parse_options ($ options , & $ task ) {
82
+ $ options = (array )$ options ;
83
+ // only common options are parsed here.
84
+ // special options should be parsed by childclass
85
+ foreach ($ options as $ key => $ value ) {
86
+ if ($ key == 'memlimit ' and $ value > 1024 * 1024 * get_config ('local_onlinejudge ' , 'maxmemlimit ' )) {
87
+ $ value = 1024 * 1024 * get_config ('local_onlinejudge ' , 'maxmemlimit ' );
88
+ }
89
+ if ($ key == 'cpulimit ' and $ value > get_config ('local_onlinejudge ' , 'maxcpulimit ' )) {
90
+ $ value = get_config ('local_onlinejudge ' , 'maxcpulimit ' );
91
+ }
92
+ $ task ->$ key = $ value ;
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Return the infomation of the compiler of specified language
98
+ *
99
+ * @param string $language ID of the language
100
+ * @return compiler information or null
101
+ */
102
+ static function get_compiler_info ($ language ) {
103
+ return array ();
104
+ }
105
+
106
+ /**
107
+ * Whether the judge is avaliable
108
+ *
109
+ * @return true for yes, false for no
110
+ */
111
+ static function is_available () {
112
+ return false ;
113
+ }
114
+
115
+ /**
116
+ * Judge the current task
117
+ *
118
+ * @return bool [updated task or false]
119
+ */
120
+ function judge () {
121
+ return false ;
122
+ }
123
+
124
+ /**
125
+ * Compare the stdout of program and the output of testcase
126
+ */
127
+ protected function diff () {
128
+ $ task = &$ this ->task ;
129
+
130
+ // convert data into UTF-8 charset if possible
131
+ $ task ->stdout = $ this ->convert_to_utf8 ($ task ->stdout );
132
+ $ task ->stderr = $ this ->convert_to_utf8 ($ task ->stderr );
133
+ $ task ->output = $ this ->convert_to_utf8 ($ task ->output );
134
+
135
+ // trim tailing return chars which are meaning less
136
+ $ task ->output = rtrim ($ task ->output , "\r\n" );
137
+ $ task ->stdout = rtrim ($ task ->stdout , "\r\n" );
138
+
139
+ if (strcmp ($ task ->output , $ task ->stdout ) == 0 ) return ONLINEJUDGE_STATUS_ACCEPTED ; else {
140
+ $ tokens = array ();
141
+ $ tok = strtok ($ task ->output , " \n\r\t" );
142
+ while ($ tok !== false ) {
143
+ $ tokens [] = $ tok ;
144
+ $ tok = strtok (" \n\r\t" );
145
+ }
146
+
147
+ $ tok = strtok ($ task ->stdout , " \n\r\t" );
148
+ foreach ($ tokens as $ anstok ) {
149
+ if ($ tok === false || $ tok !== $ anstok ) return ONLINEJUDGE_STATUS_WRONG_ANSWER ;
150
+ $ tok = strtok (" \n\r\t" );
151
+ }
152
+ if ($ tok !== false ) {
153
+ return ONLINEJUDGE_STATUS_WRONG_ANSWER ;
154
+ }
155
+ return ONLINEJUDGE_STATUS_PRESENTATION_ERROR ;
156
+ }
157
+ }
158
+
159
+ /**
160
+ * If string is not encoded in UTF-8, convert it into utf-8 charset
161
+ */
162
+ protected function convert_to_utf8 ($ string ) {
163
+ $ localwincharset = get_string ('localewincharset ' , 'langconfig ' );
164
+ if (!empty ($ localwincharset ) and !mb_check_encoding ($ string , 'UTF-8 ' ) and mb_check_encoding ($ string , $ localwincharset )) {
165
+ return core_text::convert ($ string , $ localwincharset );
166
+ } else {
167
+ return $ string ;
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Save files of current task to a temp directory
173
+ *
174
+ * @return array of the full path of saved files
175
+ */
176
+ protected function create_temp_files () {
177
+ $ dstfiles = array ();
178
+
179
+ $ fs = get_file_storage ();
180
+ $ files = $ fs ->get_area_files (context_system::instance ()->id , 'local_onlinejudge ' , 'tasks ' , $ this ->task ->id , 'sortorder ' , false );
181
+ foreach ($ files as $ file ) {
182
+ $ path = onlinejudge_get_temp_dir () . $ file ->get_filepath ();
183
+ $ fullpath = $ path . $ file ->get_filename ();
184
+ if (!check_dir_exists ($ path )) {
185
+ throw new moodle_exception ('errorcreatingdirectory ' , '' , '' , $ path );
186
+ }
187
+ $ file ->copy_content_to ($ fullpath );
188
+ $ dstfiles [] = $ fullpath ;
189
+ }
190
+
191
+ return $ dstfiles ;
192
+ }
193
+ }
0 commit comments