diff options
Diffstat (limited to 'files')
-rw-r--r-- | files/memtest | bin | 0 -> 13628 bytes | |||
-rw-r--r-- | files/process.c | 58 | ||||
-rwxr-xr-x | files/stat_log.py | 394 | ||||
-rw-r--r-- | files/testlab2.c | 195 | ||||
-rwxr-xr-x | files/testlab2.sh | 49 |
5 files changed, 696 insertions, 0 deletions
diff --git a/files/memtest b/files/memtest new file mode 100644 index 0000000..8c56b25 --- /dev/null +++ b/files/memtest | |||
Binary files differ | |||
diff --git a/files/process.c b/files/process.c new file mode 100644 index 0000000..46eb0b0 --- /dev/null +++ b/files/process.c | |||
@@ -0,0 +1,58 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <unistd.h> | ||
3 | #include <time.h> | ||
4 | #include <sys/times.h> | ||
5 | |||
6 | #define HZ 100 | ||
7 | |||
8 | void cpuio_bound(int last, int cpu_time, int io_time); | ||
9 | |||
10 | int main(int argc, char * argv[]) | ||
11 | { | ||
12 | return 0; | ||
13 | } | ||
14 | |||
15 | /* | ||
16 | * 此函数按照参数占用CPU和I/O时间 | ||
17 | * last: 函数实际占用CPU和I/O的总时间,不含在就绪队列中的时间,>=0是必须的 | ||
18 | * cpu_time: 一次连续占用CPU的时间,>=0是必须的 | ||
19 | * io_time: 一次I/O消耗的时间,>=0是必须的 | ||
20 | * 如果last > cpu_time + io_time,则往复多次占用CPU和I/O | ||
21 | * 所有时间的单位为秒 | ||
22 | */ | ||
23 | void cpuio_bound(int last, int cpu_time, int io_time) | ||
24 | { | ||
25 | struct tms start_time, current_time; | ||
26 | clock_t utime, stime; | ||
27 | int sleep_time; | ||
28 | |||
29 | while (last > 0) | ||
30 | { | ||
31 | /* CPU Burst */ | ||
32 | times(&start_time); | ||
33 | /* 其实只有t.tms_utime才是真正的CPU时间。但我们是在模拟一个 | ||
34 | * 只在用户状态运行的CPU大户,就像“for(;;);”。所以把t.tms_stime | ||
35 | * 加上很合理。*/ | ||
36 | do | ||
37 | { | ||
38 | times(¤t_time); | ||
39 | utime = current_time.tms_utime - start_time.tms_utime; | ||
40 | stime = current_time.tms_stime - start_time.tms_stime; | ||
41 | } while ( ( (utime + stime) / HZ ) < cpu_time ); | ||
42 | last -= cpu_time; | ||
43 | |||
44 | if (last <= 0 ) | ||
45 | break; | ||
46 | |||
47 | /* IO Burst */ | ||
48 | /* 用sleep(1)模拟1秒钟的I/O操作 */ | ||
49 | sleep_time=0; | ||
50 | while (sleep_time < io_time) | ||
51 | { | ||
52 | sleep(1); | ||
53 | sleep_time++; | ||
54 | } | ||
55 | last -= sleep_time; | ||
56 | } | ||
57 | } | ||
58 | |||
diff --git a/files/stat_log.py b/files/stat_log.py new file mode 100755 index 0000000..2dbe3ee --- /dev/null +++ b/files/stat_log.py | |||
@@ -0,0 +1,394 @@ | |||
1 | #!/usr/bin/python | ||
2 | import sys | ||
3 | import copy | ||
4 | |||
5 | P_NULL = 0 | ||
6 | P_NEW = 1 | ||
7 | P_READY = 2 | ||
8 | P_RUNNING = 4 | ||
9 | P_WAITING = 8 | ||
10 | P_EXIT = 16 | ||
11 | |||
12 | S_STATE = 0 | ||
13 | S_TIME = 1 | ||
14 | |||
15 | HZ = 100 | ||
16 | |||
17 | graph_title = r""" | ||
18 | -----===< COOL GRAPHIC OF SCHEDULER >===----- | ||
19 | |||
20 | [Symbol] [Meaning] | ||
21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
22 | number PID or tick | ||
23 | "-" New or Exit | ||
24 | "#" Running | ||
25 | "|" Ready | ||
26 | ":" Waiting | ||
27 | / Running with | ||
28 | "+" -| Ready | ||
29 | \and/or Waiting | ||
30 | |||
31 | -----===< !!!!!!!!!!!!!!!!!!!!!!!!! >===----- | ||
32 | """ | ||
33 | |||
34 | usage = """ | ||
35 | Usage: | ||
36 | %s /path/to/process.log [PID1] [PID2] ... [-x PID1 [PID2] ... ] [-m] [-g] | ||
37 | |||
38 | Example: | ||
39 | # Include process 6, 7, 8 and 9 in statistics only. (Unit: tick) | ||
40 | %s /path/to/process.log 6 7 8 9 | ||
41 | |||
42 | # Exclude process 0 and 1 from statistics. (Unit: tick) | ||
43 | %s /path/to/process.log -x 0 1 | ||
44 | |||
45 | # Include process 6 and 7 only and print a COOL "graphic"! (Unit: millisecond) | ||
46 | %s /path/to/process.log 6 7 -m -g | ||
47 | |||
48 | # Include all processes and print a COOL "graphic"! (Unit: tick) | ||
49 | %s /path/to/process.log -g | ||
50 | """ | ||
51 | |||
52 | class MyError(Exception): | ||
53 | pass | ||
54 | |||
55 | class DuplicateNew(MyError): | ||
56 | def __init__(self, pid): | ||
57 | args = "More than one 'N' for process %d." % pid | ||
58 | MyError.__init__(self, args) | ||
59 | |||
60 | class UnknownState(MyError): | ||
61 | def __init__(self, state): | ||
62 | args = "Unknown state '%s' found." % state | ||
63 | MyError.__init__(self, args) | ||
64 | |||
65 | class BadTime(MyError): | ||
66 | def __init__(self, time): | ||
67 | args = "The time '%d' is bad. It should >= previous line's time." % time | ||
68 | MyError.__init__(self, args) | ||
69 | |||
70 | class TaskHasExited(MyError): | ||
71 | def __init__(self, state): | ||
72 | args = "The process has exited. Why it enter '%s' state again?" % state | ||
73 | MyError.__init__(self, args) | ||
74 | |||
75 | class BadFormat(MyError): | ||
76 | def __init__(self): | ||
77 | args = "Bad log format" | ||
78 | MyError.__init__(self, args) | ||
79 | |||
80 | class RepeatState(MyError): | ||
81 | def __init__(self, pid): | ||
82 | args = "Previous state of process %d is identical with this line." % (pid) | ||
83 | MyError.__init__(self, args) | ||
84 | |||
85 | class SameLine(MyError): | ||
86 | def __init__(self): | ||
87 | args = "It is a clone of previous line." | ||
88 | MyError.__init__(self, args) | ||
89 | |||
90 | class NoNew(MyError): | ||
91 | def __init__(self, pid, state): | ||
92 | args = "The first state of process %d is '%s'. Why not 'N'?" % (pid, state) | ||
93 | MyError.__init__(self, args) | ||
94 | |||
95 | class statistics: | ||
96 | def __init__(self, pool, include, exclude): | ||
97 | if include: | ||
98 | self.pool = process_pool() | ||
99 | for process in pool: | ||
100 | if process.getpid() in include: | ||
101 | self.pool.add(process) | ||
102 | else: | ||
103 | self.pool = copy.copy(pool) | ||
104 | |||
105 | if exclude: | ||
106 | for pid in exclude: | ||
107 | if self.pool.get_process(pid): | ||
108 | self.pool.remove(pid) | ||
109 | |||
110 | def list_pid(self): | ||
111 | l = [] | ||
112 | for process in self.pool: | ||
113 | l.append(process.getpid()) | ||
114 | return l | ||
115 | |||
116 | def average_turnaround(self): | ||
117 | if len(self.pool) == 0: | ||
118 | return 0 | ||
119 | sum = 0 | ||
120 | for process in self.pool: | ||
121 | sum += process.turnaround_time() | ||
122 | return float(sum) / len(self.pool) | ||
123 | |||
124 | def average_waiting(self): | ||
125 | if len(self.pool) == 0: | ||
126 | return 0 | ||
127 | sum = 0 | ||
128 | for process in self.pool: | ||
129 | sum += process.waiting_time() | ||
130 | return float(sum) / len(self.pool) | ||
131 | |||
132 | def begin_time(self): | ||
133 | begin = 0xEFFFFF | ||
134 | for p in self.pool: | ||
135 | if p.begin_time() < begin: | ||
136 | begin = p.begin_time() | ||
137 | return begin | ||
138 | |||
139 | def end_time(self): | ||
140 | end = 0 | ||
141 | for p in self.pool: | ||
142 | if p.end_time() > end: | ||
143 | end = p.end_time() | ||
144 | return end | ||
145 | |||
146 | def throughput(self): | ||
147 | return len(self.pool) * HZ / float(self.end_time() - self.begin_time()) | ||
148 | |||
149 | def print_graphic(self): | ||
150 | begin = self.begin_time() | ||
151 | end = self.end_time() | ||
152 | |||
153 | print graph_title | ||
154 | |||
155 | for i in range(begin, end+1): | ||
156 | line = "%5d " % i | ||
157 | for p in self.pool: | ||
158 | state = p.get_state(i) | ||
159 | if state & P_NEW: | ||
160 | line += "-" | ||
161 | elif state == P_READY or state == P_READY | P_WAITING: | ||
162 | line += "|" | ||
163 | elif state == P_RUNNING: | ||
164 | line += "#" | ||
165 | elif state == P_WAITING: | ||
166 | line += ":" | ||
167 | elif state & P_EXIT: | ||
168 | line += "-" | ||
169 | elif state == P_NULL: | ||
170 | line += " " | ||
171 | elif state & P_RUNNING: | ||
172 | line += "+" | ||
173 | else: | ||
174 | assert False | ||
175 | if p.get_state(i-1) != state and state != P_NULL: | ||
176 | line += "%-3d" % p.getpid() | ||
177 | else: | ||
178 | line += " " | ||
179 | print line | ||
180 | |||
181 | class process_pool: | ||
182 | def __init__(self): | ||
183 | self.list = [] | ||
184 | |||
185 | def get_process(self, pid): | ||
186 | for process in self.list: | ||
187 | if process.getpid() == pid: | ||
188 | return process | ||
189 | return None | ||
190 | |||
191 | def remove(self, pid): | ||
192 | for process in self.list: | ||
193 | if process.getpid() == pid: | ||
194 | self.list.remove(process) | ||
195 | |||
196 | def new(self, pid, time): | ||
197 | p = self.get_process(pid) | ||
198 | if p: | ||
199 | if pid != 0: | ||
200 | raise DuplicateNew(pid) | ||
201 | else: | ||
202 | p.states=[(P_NEW, time)] | ||
203 | else: | ||
204 | p = process(pid, time) | ||
205 | self.list.append(p) | ||
206 | return p | ||
207 | |||
208 | def add(self, p): | ||
209 | self.list.append(p) | ||
210 | |||
211 | def __len__(self): | ||
212 | return len(self.list) | ||
213 | |||
214 | def __iter__(self): | ||
215 | return iter(self.list) | ||
216 | |||
217 | class process: | ||
218 | def __init__(self, pid, time): | ||
219 | self.pid = pid | ||
220 | self.states = [(P_NEW, time)] | ||
221 | |||
222 | def getpid(self): | ||
223 | return self.pid | ||
224 | |||
225 | def change_state(self, state, time): | ||
226 | last_state, last_time = self.states[-1] | ||
227 | if state == P_NEW: | ||
228 | raise DuplicateNew(pid) | ||
229 | if time < last_time: | ||
230 | raise BadTime(time) | ||
231 | if last_state == P_EXIT: | ||
232 | raise TaskHasExited(state) | ||
233 | if last_state == state and self.pid != 0: # task 0 can have duplicate state | ||
234 | raise RepeatState(self.pid) | ||
235 | |||
236 | self.states.append((state, time)) | ||
237 | |||
238 | def get_state(self, time): | ||
239 | rval = P_NULL | ||
240 | combo = P_NULL | ||
241 | if self.begin_time() <= time <= self.end_time(): | ||
242 | for state, s_time in self.states: | ||
243 | if s_time < time: | ||
244 | rval = state | ||
245 | elif s_time == time: | ||
246 | combo |= state | ||
247 | else: | ||
248 | break | ||
249 | if combo: | ||
250 | rval = combo | ||
251 | return rval | ||
252 | |||
253 | def turnaround_time(self): | ||
254 | return self.states[-1][S_TIME] - self.states[0][S_TIME] | ||
255 | |||
256 | def waiting_time(self): | ||
257 | return self.state_last_time(P_READY) | ||
258 | |||
259 | def cpu_time(self): | ||
260 | return self.state_last_time(P_RUNNING) | ||
261 | |||
262 | def io_time(self): | ||
263 | return self.state_last_time(P_WAITING) | ||
264 | |||
265 | def state_last_time(self, state): | ||
266 | time = 0 | ||
267 | state_begin = 0 | ||
268 | for s,t in self.states: | ||
269 | if s == state: | ||
270 | state_begin = t | ||
271 | elif state_begin != 0: | ||
272 | assert state_begin <= t | ||
273 | time += t - state_begin | ||
274 | state_begin = 0 | ||
275 | return time | ||
276 | |||
277 | |||
278 | def begin_time(self): | ||
279 | return self.states[0][S_TIME] | ||
280 | |||
281 | def end_time(self): | ||
282 | return self.states[-1][S_TIME] | ||
283 | |||
284 | # Enter point | ||
285 | if len(sys.argv) < 2: | ||
286 | print usage.replace("%s", sys.argv[0]) | ||
287 | sys.exit(0) | ||
288 | |||
289 | # parse arguments | ||
290 | include = [] | ||
291 | exclude = [] | ||
292 | unit_ms = False | ||
293 | graphic = False | ||
294 | ex_mark = False | ||
295 | |||
296 | try: | ||
297 | for arg in sys.argv[2:]: | ||
298 | if arg == '-m': | ||
299 | unit_ms = True | ||
300 | continue | ||
301 | if arg == '-g': | ||
302 | graphic = True | ||
303 | continue | ||
304 | if not ex_mark: | ||
305 | if arg == '-x': | ||
306 | ex_mark = True | ||
307 | else: | ||
308 | include.append(int(arg)) | ||
309 | else: | ||
310 | exclude.append(int(arg)) | ||
311 | except ValueError: | ||
312 | print "Bad argument '%s'" % arg | ||
313 | sys.exit(-1) | ||
314 | |||
315 | # parse log file and construct processes | ||
316 | processes = process_pool() | ||
317 | |||
318 | f = open(sys.argv[1], "r") | ||
319 | |||
320 | # Patch process 0's New & Run state | ||
321 | processes.new(0, 40).change_state(P_RUNNING, 40) | ||
322 | |||
323 | try: | ||
324 | prev_time = 0 | ||
325 | prev_line = "" | ||
326 | for lineno, line in enumerate(f): | ||
327 | |||
328 | if line == prev_line: | ||
329 | raise SameLine | ||
330 | prev_line = line | ||
331 | |||
332 | fields = line.split("\t") | ||
333 | if len(fields) != 3: | ||
334 | raise BadFormat | ||
335 | |||
336 | pid = int(fields[0]) | ||
337 | s = fields[1].upper() | ||
338 | |||
339 | time = int(fields[2]) | ||
340 | if time < prev_time: | ||
341 | raise BadTime(time) | ||
342 | prev_time = time | ||
343 | |||
344 | p = processes.get_process(pid) | ||
345 | |||
346 | state = P_NULL | ||
347 | if s == 'N': | ||
348 | processes.new(pid, time) | ||
349 | elif s == 'J': | ||
350 | state = P_READY | ||
351 | elif s == 'R': | ||
352 | state = P_RUNNING | ||
353 | elif s == 'W': | ||
354 | state = P_WAITING | ||
355 | elif s == 'E': | ||
356 | state = P_EXIT | ||
357 | else: | ||
358 | raise UnknownState(s) | ||
359 | if state != P_NULL: | ||
360 | if not p: | ||
361 | raise NoNew(pid, s) | ||
362 | p.change_state(state, time) | ||
363 | except MyError, err: | ||
364 | print "Error at line %d: %s" % (lineno+1, err) | ||
365 | sys.exit(0) | ||
366 | |||
367 | # Stats | ||
368 | stats = statistics(processes, include, exclude) | ||
369 | att = stats.average_turnaround() | ||
370 | awt = stats.average_waiting() | ||
371 | if unit_ms: | ||
372 | unit = "ms" | ||
373 | att *= 1000/HZ | ||
374 | awt *= 1000/HZ | ||
375 | else: | ||
376 | unit = "tick" | ||
377 | print "(Unit: %s)" % unit | ||
378 | print "Process Turnaround Waiting CPU Burst I/O Burst" | ||
379 | for pid in stats.list_pid(): | ||
380 | p = processes.get_process(pid) | ||
381 | tt = p.turnaround_time() | ||
382 | wt = p.waiting_time() | ||
383 | cpu = p.cpu_time() | ||
384 | io = p.io_time() | ||
385 | |||
386 | if unit_ms: | ||
387 | print "%7d %10d %7d %9d %9d" % (pid, tt*1000/HZ, wt*1000/HZ, cpu*1000/HZ, io*1000/HZ) | ||
388 | else: | ||
389 | print "%7d %10d %7d %9d %9d" % (pid, tt, wt, cpu, io) | ||
390 | print "Average: %10.2f %7.2f" % (att, awt) | ||
391 | print "Throughout: %.2f/s" % (stats.throughput()) | ||
392 | |||
393 | if graphic: | ||
394 | stats.print_graphic() | ||
diff --git a/files/testlab2.c b/files/testlab2.c new file mode 100644 index 0000000..bd97b76 --- /dev/null +++ b/files/testlab2.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Compile: "gcc testlab2.c" | ||
3 | * Run: "./a.out" | ||
4 | */ | ||
5 | |||
6 | #include <string.h> | ||
7 | #include <assert.h> | ||
8 | #include <stdio.h> | ||
9 | #include <errno.h> | ||
10 | #include <stdlib.h> | ||
11 | #define __LIBRARY__ | ||
12 | #include <unistd.h> | ||
13 | |||
14 | _syscall2(int, whoami,char*,name,unsigned int,size); | ||
15 | _syscall1(int, iam, const char*, name); | ||
16 | |||
17 | #define MAX_NAME_LEN 23 | ||
18 | #define NAMEBUF_SIZE (MAX_NAME_LEN + 1) | ||
19 | /* truncate a long name to SHORT_NAME_LEN for display */ | ||
20 | #define SHORT_NAME_LEN (MAX_NAME_LEN + 2) | ||
21 | |||
22 | /* name score */ | ||
23 | #define TEST_CASE { \ | ||
24 | {"x", 10, 1, NAMEBUF_SIZE, 1},\ | ||
25 | {"sunner", 10, 6, NAMEBUF_SIZE, 6},\ | ||
26 | {"Twenty-three characters", 5, 23, NAMEBUF_SIZE, 23},\ | ||
27 | {"123456789009876543211234", 5, -1, 0, -1},\ | ||
28 | {"abcdefghijklmnopqrstuvwxyz", 5, -1, 0, -1},\ | ||
29 | {"Linus Torvalds", 5, 14, NAMEBUF_SIZE, 14},\ | ||
30 | {"", 5, 0, NAMEBUF_SIZE, 0},\ | ||
31 | {"whoami(0xbalabala, 10)", 5, 22, 10, -1},\ | ||
32 | {NULL, 0, 0, 0, 0} /* End of cases */ \ | ||
33 | } | ||
34 | /*改动一:增加size,和rval2*/ | ||
35 | |||
36 | int test(const char* name, int max_score, int expected_rval1, int size, int expected_rval2); | ||
37 | void print_message(const char* msgfmt, const char* name); | ||
38 | |||
39 | struct test_case | ||
40 | { | ||
41 | char *name; | ||
42 | int score; | ||
43 | int rval1; /* return value of iam() */ | ||
44 | /*改动2:增加size,和rval2定义*/ | ||
45 | int size; /*Patch for whoami,2009.11.2*/ | ||
46 | int rval2; /* return value of whoami() */ | ||
47 | }; | ||
48 | |||
49 | int main(void) | ||
50 | { | ||
51 | struct test_case cases[] = TEST_CASE; | ||
52 | |||
53 | int total_score=0, i=0; | ||
54 | |||
55 | while (cases[i].score != 0) | ||
56 | { | ||
57 | int score; | ||
58 | |||
59 | printf("Test case %d:", i+1); | ||
60 | |||
61 | /*改动3:增加size,和rval2的参数阿*/ | ||
62 | score = test( cases[i].name, | ||
63 | cases[i].score, | ||
64 | cases[i].rval1, | ||
65 | cases[i].size, | ||
66 | cases[i].rval2 ); | ||
67 | |||
68 | total_score += score; | ||
69 | i++; | ||
70 | } | ||
71 | |||
72 | printf("Final result: %d%%\n", total_score); | ||
73 | return 0; | ||
74 | |||
75 | } | ||
76 | /*改动4:增加size,和rval2的声明*/ | ||
77 | int test(const char* name, int max_score, int expected_rval1, int size, int expected_rval2) | ||
78 | { | ||
79 | int rval; | ||
80 | int len; | ||
81 | char * gotname; | ||
82 | int score=-1; | ||
83 | |||
84 | assert(name != NULL); | ||
85 | |||
86 | print_message("name = \"%s\", length = %d...", name); | ||
87 | |||
88 | /*Test iam()*/ | ||
89 | len = strlen(name); | ||
90 | rval = iam(name); | ||
91 | /* printf("Return value = %d\n", rval);*/ | ||
92 | |||
93 | /*改动5:增加的expected_rval1*/ | ||
94 | if (rval == expected_rval1) | ||
95 | { | ||
96 | if (rval == -1 && errno == EINVAL) /*The system call can detect bad name*/ | ||
97 | { | ||
98 | /* print_message("Long name, %s(%d), detected.\n", name);*/ | ||
99 | printf("PASS\n"); | ||
100 | score = max_score; | ||
101 | } | ||
102 | else if (rval == -1 && errno != EINVAL) | ||
103 | { | ||
104 | printf("\nERROR iam(): Bad errno %d. It should be %d(EINVAL).\n", errno, EINVAL); | ||
105 | score = 0; | ||
106 | } | ||
107 | /* iam() is good. Test whoami() next. */ | ||
108 | } | ||
109 | else | ||
110 | { | ||
111 | printf("\nERROR iam(): Return value is %d. It should be %d.\n", rval, expected_rval1); | ||
112 | score = 0; | ||
113 | } | ||
114 | |||
115 | if (score != -1) | ||
116 | return score; | ||
117 | |||
118 | /*Test whoami()*/ | ||
119 | gotname = (char*)malloc(len+1); | ||
120 | if (gotname == NULL) | ||
121 | exit(-1); | ||
122 | |||
123 | memset(gotname, 0, len+1); | ||
124 | |||
125 | /* printf("Get: buffer length = %d.\n", len+1); */ | ||
126 | |||
127 | rval = whoami(gotname, size); | ||
128 | /* printf("Return value = %d\n", rval); */ | ||
129 | |||
130 | /*改动6:增加的expected_rval2*/ | ||
131 | /*改动++:比较多 ,但还是顺序的改改*/ | ||
132 | |||
133 | if(rval == expected_rval2) | ||
134 | { | ||
135 | if(rval == -1) | ||
136 | { | ||
137 | printf("PASS\n"); | ||
138 | score = max_score; | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | if (strcmp(gotname, name) == 0) | ||
143 | { | ||
144 | /* print_message("Great! We got %s(%d) finally!\n", gotname); */ | ||
145 | printf("PASS\n"); | ||
146 | score = max_score; | ||
147 | } | ||
148 | else | ||
149 | { | ||
150 | print_message("\nERROR whoami(): we got %s(%d). ", gotname); | ||
151 | print_message("It should be %s(%d).\n", name); | ||
152 | score = 0; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | else if (rval == -1) | ||
157 | { | ||
158 | printf("\nERROR whoami(): Return value is -1 and errno is %d. Why?\n", errno); | ||
159 | score = 0; | ||
160 | } | ||
161 | else | ||
162 | { | ||
163 | printf("\nERROR whoami(): Return value should be %d, not %d.\n", expected_rval2, rval); | ||
164 | score = 0; | ||
165 | } | ||
166 | |||
167 | free(gotname); | ||
168 | assert(score != -1); | ||
169 | |||
170 | return score; | ||
171 | } | ||
172 | |||
173 | void print_message(const char* msgfmt, const char* name) | ||
174 | { | ||
175 | char short_name[SHORT_NAME_LEN + 4] = {0}; | ||
176 | int len; | ||
177 | |||
178 | len = strlen(name); | ||
179 | |||
180 | if (len == 0) | ||
181 | { | ||
182 | strcpy(short_name, "NULL"); | ||
183 | } | ||
184 | else if (len <= SHORT_NAME_LEN) | ||
185 | { | ||
186 | strcpy(short_name, name); | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | memset(short_name, '.', SHORT_NAME_LEN+3); | ||
191 | memcpy(short_name, name, SHORT_NAME_LEN); | ||
192 | } | ||
193 | |||
194 | printf(msgfmt, short_name, len); | ||
195 | } | ||
diff --git a/files/testlab2.sh b/files/testlab2.sh new file mode 100755 index 0000000..7f79876 --- /dev/null +++ b/files/testlab2.sh | |||
@@ -0,0 +1,49 @@ | |||
1 | #/bin/sh | ||
2 | |||
3 | string1="Sunner" | ||
4 | string2="Richard Stallman" | ||
5 | string3="This is a very very long string!" | ||
6 | |||
7 | score1=10 | ||
8 | score2=10 | ||
9 | score3=10 | ||
10 | |||
11 | expected1="Sunner" | ||
12 | expected2="Richard Stallman" | ||
13 | expected3="Richard Stallman" | ||
14 | |||
15 | echo Testing string:$string1 | ||
16 | ./iam "$string1" | ||
17 | result=`./whoami` | ||
18 | if [ "$result" = "$expected1" ]; then | ||
19 | echo PASS. | ||
20 | else | ||
21 | score1=0 | ||
22 | echo FAILED. | ||
23 | fi | ||
24 | score=$score1 | ||
25 | |||
26 | echo Testing string:$string2 | ||
27 | ./iam "$string2" | ||
28 | result=`./whoami` | ||
29 | if [ "$result" = "$expected2" ]; then | ||
30 | echo PASS. | ||
31 | else | ||
32 | score2=0 | ||
33 | echo FAILED. | ||
34 | fi | ||
35 | score=$score+$score2 | ||
36 | |||
37 | echo Testing string:$string3 | ||
38 | ./iam "$string3" | ||
39 | result=`./whoami` | ||
40 | if [ "$result" = "$expected3" ]; then | ||
41 | echo PASS. | ||
42 | else | ||
43 | score3=0 | ||
44 | echo FAILED. | ||
45 | fi | ||
46 | score=$score+$score3 | ||
47 | |||
48 | let "totalscore=$score" | ||
49 | echo Score: $score = $totalscore% | ||