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