- Convert tditest to PSEH instead of a broken MSVC SEH attempt
[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 void sh_outp(char *cur_string)
123 {
124 int symbol;
125 putchar('\n');
126 putchar('\n');
127 for(symbol=3;putchar(cur_string[symbol]); symbol++);
128 }
129
130 void th_outp(char *cur_string, char *THtag)
131 {
132 int symbol;
133 putchar('\n');
134 putchar('\n');
135 putchar('\t');
136 putchar('\t');
137 SetCl(ITALIC);
138 for(symbol=3;putchar(THtag[symbol]); symbol++);
139 putchar('\n');
140 SetCl(NORMAL);
141 }
142
143 void text_outp(char *cur_string)
144 {
145 char TagFlag=0;
146 int symbol=0;
147
148 if(cur_string[0]=='.')
149 while(cur_string[symbol]!=' ')
150 symbol++;
151
152 if(symbol) TagFlag=1;
153
154 for(;cur_string[symbol]!='\n'; symbol++)
155 putchar(cur_string[symbol]);
156 putchar(' ');
157 }
158
159 int
160 AnalyzeFile()
161 {
162 char *cur_string=(char*)malloc(sizeof(char)*MAXLINE);
163 char *THtag=(char*)malloc(sizeof(char)*MAXLINE);
164
165
166
167
168 while(fgets(cur_string,MAXLINE,manfile))
169
170 /* TAGs processing */
171 if((cur_string[0]=='.')&&(cur_string[1]=='S')&&
172 (cur_string[2]=='H')) // .SH tag
173 {
174 SetCl(BOLD);
175 sh_outp(cur_string);
176 SetCl(NORMAL);
177 }
178 else
179 if((cur_string[0]=='.')&&(cur_string[1]=='I')&&
180 (cur_string[2]==' ')) // .I tag
181 {
182 SetCl(ITALIC);
183 text_outp(cur_string);
184 SetCl(NORMAL);
185 }
186 else
187 if((cur_string[0]=='.')&&(cur_string[1]=='/')&&
188 (cur_string[2]=='\"')); // ./" tag (comment)
189
190 else
191 if((cur_string[0]=='.')&&(cur_string[1]=='T')&&
192 (cur_string[2]=='H')) // .TH tag
193 {
194 strcpy(THtag,cur_string);
195 }
196 else
197 if((cur_string[0]=='.')&&(cur_string[1]=='B')&&
198 (cur_string[2]==' ')) // .B tag
199 {
200 SetCl(BOLD);
201 text_outp(cur_string);
202 SetCl(NORMAL);
203 }
204 else
205 if((cur_string[0]=='.')&&(cur_string[1]=='N')&&
206 (cur_string[2]=='L'))
207 {
208 putchar('\n');
209 putchar(' ');
210 }
211
212 else text_outp(cur_string); // print plane text
213 th_outp(cur_string, THtag);
214 /* END of TAGs processing */
215 return 0;
216 }
217
218
219 int
220 main(int argc, char *argv[])
221 {
222
223 switch(argc)
224 {
225 case 1: Usage(); break;
226 case 2: AnalyzeArgv(argv[1]);break;
227 default: Usage();break;
228 }
229
230 if(OpenFlag)CloseF();
231 SetCl(NORMAL);
232 return 0;
233 }
234