Merging r37048, r37051, r37052, r37055 from the-real-msvc branch
[reactos.git] / rosapps / applications / sysutils / man / man.c
1 /*
2 * FILE : man.c
3 * NATIVE NAME: ReactOS manual browser
4 * AUTHOR : Semyon Novikov (tappak)
5 * PROJECT : ReactOS Operating System
6 * DESCRIPTION: manual file browser (Use Linux man file syntax)
7 * DATE : 2004-03-29
8 * LICENSE : GPL
9 */
10
11 /* Known issues.
12 * 1. Scroll screen
13 * 2. Non ENVIRONMENT manpath varrible
14 * 3. At the end of man page must be ./" tag!
15 */
16
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <windows.h>
21 #include <wincon.h>
22
23 #define MAXLINE 256
24 #define BOLD 7|9
25 #define ITALIC 3|9
26 #define NORMAL 7|0
27
28 /*===[functions]===*/
29 void SetCl(WORD cl);
30 int OpenF(char* name);
31 int CloseF(void);
32 void Usage(void);
33 int AnalyzeArgv(char *);
34 int AnalyzeFile();
35 /*=================*/
36
37 /*====[Globals]====*/
38 FILE* manfile;
39 char OpenFlag=0;
40 char manpath[MAXLINE]="c:\\man\\";
41 /*=================*/
42
43 void
44 SetCl(WORD cl)
45 {
46 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),cl);
47 }
48
49 int
50 OpenF(char* name)
51 {
52 int retval=0;
53 char *manpath_local=(char*)malloc(sizeof(char)*MAXLINE);
54
55 strcpy(manpath_local, manpath); //save mandir value
56
57 if((manfile=fopen((strcat(manpath_local,name)),"r"))!=NULL)
58 {
59 OpenFlag=1;
60 AnalyzeFile();
61 }
62 else
63 retval=-1;
64
65 strcpy(manpath_local, manpath);
66 return retval;
67 }
68
69 int
70 CloseF()
71 {
72 int retval=0;
73
74 if(fclose(manfile))
75 OpenFlag=0;
76 else retval=-1;
77
78 return retval;
79 }
80
81 void
82 Usage()
83 {
84 puts("usage: man [command]");
85 puts("see \"man man\" for details");
86 }
87
88 int
89 AnalyzeArgv(char *argument)
90 {
91 int element=0;
92 char HelpFlag=0;
93 char *keys[]={"--help","/h","/?","-h"};
94 char *sections[]={".1",".2",".3",".4",".5",".6",".7",".8",".9"};
95 char *filename=(char*)malloc(sizeof(char)*MAXLINE);
96
97 strcpy(filename,argument); //save argument value
98
99 for(element=0; element < 5;element++)
100 if(!strcmp(keys[element],argument))
101 {
102 Usage();
103 HelpFlag=1;
104 }
105
106 element = 0;
107
108 if(!HelpFlag)
109
110 if(OpenF(filename))
111 while(OpenF(strcat(filename,sections[element])) && (element<9))
112 {
113 strcpy(filename,argument);
114 element++;
115 }
116
117 if(element>8) printf("No manual for %s\n",argument);
118
119 return element;
120 }
121
122 int
123 AnalyzeFile()
124 {
125 char *cur_string=(char*)malloc(sizeof(char)*MAXLINE);
126 int symbol=0;
127 char *THtag=(char*)malloc(sizeof(char)*MAXLINE);
128
129
130 void sh_outp(void)
131 {
132 putchar('\n');
133 putchar('\n');
134 for(symbol=3;putchar(cur_string[symbol]); symbol++);
135 }
136
137 void th_outp(void)
138 {
139 putchar('\n');
140 putchar('\n');
141 putchar('\t');
142 putchar('\t');
143 SetCl(ITALIC);
144 for(symbol=3;putchar(THtag[symbol]); symbol++);
145 putchar('\n');
146 SetCl(NORMAL);
147 }
148
149 void text_outp(void)
150 {
151 char TagFlag=0;
152 symbol=0;
153
154 if(cur_string[0]=='.')
155 while(cur_string[symbol]!=' ')
156 symbol++;
157
158 if(symbol) TagFlag=1;
159
160 for(;cur_string[symbol]!='\n'; symbol++)
161 putchar(cur_string[symbol]);
162 putchar(' ');
163 }
164
165 while(fgets(cur_string,MAXLINE,manfile))
166
167 /* TAGs processing */
168 if((cur_string[0]=='.')&&(cur_string[1]=='S')&&
169 (cur_string[2]=='H')) // .SH tag
170 {
171 SetCl(BOLD);
172 sh_outp();
173 SetCl(NORMAL);
174 }
175 else
176 if((cur_string[0]=='.')&&(cur_string[1]=='I')&&
177 (cur_string[2]==' ')) // .I tag
178 {
179 SetCl(ITALIC);
180 text_outp();
181 SetCl(NORMAL);
182 }
183 else
184 if((cur_string[0]=='.')&&(cur_string[1]=='/')&&
185 (cur_string[2]=='\"')); // ./" tag (comment)
186
187 else
188 if((cur_string[0]=='.')&&(cur_string[1]=='T')&&
189 (cur_string[2]=='H')) // .TH tag
190 {
191 strcpy(THtag,cur_string);
192 }
193 else
194 if((cur_string[0]=='.')&&(cur_string[1]=='B')&&
195 (cur_string[2]==' ')) // .B tag
196 {
197 SetCl(BOLD);
198 text_outp();
199 SetCl(NORMAL);
200 }
201 else
202 if((cur_string[0]=='.')&&(cur_string[1]=='N')&&
203 (cur_string[2]=='L'))
204 {
205 putchar('\n');
206 putchar(' ');
207 }
208
209 else text_outp(); // print plane text
210 th_outp();
211 /* END of TAGs processing */
212 return 0;
213 }
214
215
216 int
217 main(int argc, char *argv[])
218 {
219
220 switch(argc)
221 {
222 case 1: Usage(); break;
223 case 2: AnalyzeArgv(argv[1]);break;
224 default: Usage();break;
225 }
226
227 if(OpenFlag)CloseF();
228 SetCl(NORMAL);
229 return 0;
230 }
231