xref: /netbsd-src/external/cddl/dtracetoolkit/dist/Bin/guess.d (revision c29d51755812ace2e87aeefdb06cb2b4dac7087a)
1 #!/usr/sbin/dtrace -wqs
2 /*
3  * guess.d - guessing game in D (DTrace)
4  *
5  * $Id: guess.d,v 1.1.1.1 2015/09/30 22:01:07 christos Exp $
6  *
7  * USAGE: guess.d
8  *
9  * SEE: http://www.brendangregg.com/guessinggame.html
10  *
11  * This is written to demonstrate this language versus the same program
12  * written in other languages.
13  *
14  * 11-May-2005	Brendan Gregg	Created this.
15  */
16 
17 inline string scorefile = "highscores_d";
18 
19 dtrace:::BEGIN
20 {
21 	printf("guess.d - Guess a number between 1 and 100\n\n");
22 	num = 1;
23 	state = 1;
24 
25 	/* Generate random number */
26 	answer = (rand() % 100) + 1;
27 	answer = answer > 0 ? answer : - answer;
28 }
29 
30 syscall::write:entry
31 /state == 1 && pid == $pid/
32 {
33 	state = 2;
34 	printf("Enter guess %d: ", num);
35 	system("read guess");
36 	pos = 0;
37 }
38 
39 syscall::read:entry
40 /state == 2 && ppid == $pid && arg0 == 3/
41 {
42 	self->inguess = 1;
43 	self->buf = arg1;
44 }
45 
46 syscall::read:return
47 /self->inguess/
48 {
49 	key = copyin(self->buf, arg0);
50 	keys[pos] = *(char *)key;
51 	self->buf = 0;
52 	pos++;
53 }
54 
55 syscall::read:return
56 /self->inguess && keys[pos-1] == '\n'/
57 {
58 	pos -= 2;
59 	fac = 1;
60 	guess = fac * (keys[pos] - '0');
61 	pos--;
62 	fac *= 10;
63 	guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
64 	pos--;
65 	fac *= 10;
66 	guess = pos >= 0 ? guess + fac * (keys[pos] - '0') : guess;
67 	self->doneguess = 1;
68 }
69 
70 syscall::read:return
71 /self->inguess/
72 {
73 	self->inguess = 0;
74 }
75 
76 /* Play game */
77 syscall::read:return
78 /self->doneguess && guess == answer/
79 {
80 	printf("Correct! That took %d guesses.\n\n", num);
81 	self->doneguess = 0;
82 	state = 3;
83 	printf("Please enter your name: ");
84 	system("/usr/bin/read name");
85 }
86 
87 syscall::read:return
88 /self->doneguess && guess != answer/
89 {
90 	num++;
91 
92 	printf("%s...\n", guess < answer ? "Higher" : "Lower");
93 
94 	printf("Enter guess %d: ", num);
95 	system("read line");
96 	pos = 0;
97 }
98 
99 syscall::read:entry
100 /state == 3 && curthread->t_procp->p_parent->p_ppid == $pid && arg0 == 0/
101 {
102 	self->inname = 1;
103 	self->buf = arg1;
104 }
105 
106 /* Save high score */
107 syscall::read:return
108 /self->inname/
109 {
110 	self->inname = 0;
111 	name = stringof(copyin(self->buf, arg0 - 1));
112 	system("echo %s %d >> %s", name, num, scorefile);
113 
114 	/* Print high scores */
115 	printf("\nPrevious high scores,\n");
116 	system("cat %s", scorefile);
117 	exit(0);
118 }
119