be65a89060b17e00687da26eed1ce80e7a013e5b
[openafs.git] / src / WINNT / license / main.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <windows.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include "multistring.h"
14
15 #ifndef iswhite
16 #define iswhite(_ch) (((_ch)==' ') || ((_ch)=='\t'))
17 #endif
18 #ifndef iseol
19 #define iseol(_ch) (((_ch)=='\n') || ((_ch)=='\r'))
20 #endif
21 #ifndef iswhiteeol
22 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
23 #endif
24
25 namespace g
26    {
27    int CodePage;
28    };
29
30
31 LPTSTR EscapeSpecialCharacters (LPTSTR pachIn, size_t cchIn)
32 {
33    static LPTSTR pszOut = NULL;
34    static size_t cchOut = 0;
35
36    size_t cchReq = cchIn * 2 + 1;
37    if (pszOut && (cchOut < cchReq))
38       {
39       free(pszOut);
40       pszOut = NULL;
41       cchOut = 0;
42       }
43
44    if (!pszOut)
45       {
46       pszOut = (LPTSTR)malloc(cchReq);
47       cchOut = cchReq;
48       }
49
50    if (pszOut)
51       {
52       LPTSTR pchOut = pszOut;
53
54       for ( ; cchIn; --cchIn)
55          {
56          if (*pachIn == '}')
57             {
58             *pchOut++ = TEXT('\\');
59             *pchOut++ = TEXT('\'');
60             *pchOut++ = TEXT('7');
61             *pchOut++ = TEXT('D');
62             pachIn++;
63             }
64          else
65             {
66             if (strchr ("\\{", *pachIn))
67                *pchOut++ = TEXT('\\');
68             *pchOut++ = *pachIn++;
69             }
70          }
71
72       *pchOut = TEXT('\0');
73       }
74
75    return pszOut;
76 }
77
78
79 BOOL FormatFile (LPTSTR pszName, LPTSTR pszText)
80 {
81    // Find the appropriate output filename
82    //
83    TCHAR szName[ MAX_PATH ];
84    lstrcpy (szName, pszName);
85
86    LPTSTR pchSlash = NULL;
87    for (LPTSTR pch = szName; *pch; ++pch)
88       {
89       if (*pch == TEXT('\\'))
90          pchSlash = NULL;
91       else if (*pch == TEXT('.'))
92          pchSlash = pch;
93       }
94    if (pchSlash)
95       lstrcpy (pchSlash, TEXT(".rtf"));
96    else // (!pchSlash)
97       lstrcat (szName, TEXT(".rtf"));
98
99    // Open an output file handle
100    //
101    HANDLE hFile;
102    if ((hFile = CreateFile (szName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
103       {
104       printf ("failed to create %s; error %lu\n", szName, GetLastError());
105       return FALSE;
106       }
107
108    // Write the RTF prolog
109    //
110    char *pszPROLOG = "{\\rtf1\\ansi\\deff0\\deftab720\\ansicpg%lu\n"
111                      "{\\colortbl\\red0\\green0\\blue0;}\\pard";
112
113    char szProlog[ 1024 ];
114    wsprintf (szProlog, pszPROLOG, g::CodePage);
115
116    DWORD dwWrote;
117    WriteFile (hFile, szProlog, lstrlen(szProlog), &dwWrote, NULL);
118
119    // Translate the file itself
120    //
121    BOOL fAllowCRLF = FALSE;
122    BOOL fInFormatted = FALSE;
123    size_t cFormatted = FALSE;
124    LPTSTR pchNext = NULL;
125    for (LPTSTR pchRead = pszText; pchRead && *pchRead; pchRead = pchNext)
126       {
127       while (iswhiteeol(*pchRead))
128          ++pchRead;
129       if (!*pchRead)
130          break;
131
132       if (*pchRead == '<')
133          {
134          pchNext = &pchRead[1];
135          while (*pchNext && (*pchNext != '>'))
136             ++pchNext;
137          if (*pchNext == '>')
138             ++pchNext;
139
140          // If this was a "<p>", write an EOL.
141          // If this was a "<d>", write paragraph-header formatting info.
142          // If this was a "<?>", write an EOL.
143          //
144          if (tolower(pchRead[1]) == '?')
145             {
146             if (fAllowCRLF)
147                WriteFile (hFile, "\r\n\\par ", lstrlen("\r\n\\par "), &dwWrote, NULL);
148             }
149          else if (tolower(pchRead[1]) == 'p')
150             {
151             if (fAllowCRLF)
152                WriteFile (hFile, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote, NULL);
153             if (fInFormatted)
154                {
155                char *pszPLAIN = "\\plain\\fs20 ";
156                WriteFile (hFile, pszPLAIN, lstrlen(pszPLAIN), &dwWrote, NULL);
157                }
158             fInFormatted = FALSE;
159             }
160          else if (tolower(pchRead[1]) == 'd')
161             {
162             if (fAllowCRLF)
163                WriteFile (hFile, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote, NULL);
164
165             char *pszWrite;
166             if ((++cFormatted) <= 2)
167                pszWrite = "\\plain\\fs28\\b ";
168             else // (cFormatted > 2)
169                pszWrite = "\\plain\\fs24\\b ";
170
171             WriteFile (hFile, pszWrite, lstrlen(pszWrite), &dwWrote, NULL);
172
173             fInFormatted = TRUE;
174             }
175          }
176       else // (*pchRead != '<')
177          {
178          pchNext = &pchRead[1];
179          while (*pchNext && (*pchNext != '<') && !iseol(*pchNext))
180             ++pchNext;
181
182          LPTSTR pszEscaped;
183          if ((pszEscaped = EscapeSpecialCharacters (pchRead, pchNext - pchRead)) == NULL)
184             break;
185
186          WriteFile (hFile, pszEscaped, lstrlen(pszEscaped), &dwWrote, NULL);
187          fAllowCRLF = TRUE;
188          }
189       }
190
191    // Write the RTF trailer
192    //
193    char *pszTRAILER = "\\par }";
194
195    WriteFile (hFile, pszTRAILER, lstrlen(pszTRAILER), &dwWrote, NULL);
196
197    SetEndOfFile (hFile);
198    CloseHandle (hFile);
199    return TRUE;
200 }
201
202
203 BOOL TranslateFile (LPTSTR psz)
204 {
205    BOOL rc = TRUE;
206
207    // First open the file and read it into memory.
208    //
209    HANDLE hFile;
210    if ((hFile = CreateFile (psz, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
211       {
212       printf ("failed to open %s; error %lu\n", psz, GetLastError());
213       return FALSE;
214       }
215
216    DWORD cbSource;
217    if ((cbSource = GetFileSize (hFile, NULL)) != 0)
218       {
219       LPTSTR abSource = (LPTSTR)malloc(cbSource + 1);
220           memset(abSource, 0x00, cbSource + 1);
221
222       DWORD dwRead;
223       if (!ReadFile (hFile, abSource, cbSource, &dwRead, NULL) || cbSource != dwRead)
224          {
225          printf ("failed to read %s; error %lu\n", psz, GetLastError());
226          rc = FALSE;
227          }
228       else
229          {
230          DWORD cbTarget = cbSource * 4;
231          LPSTR abTarget = (LPSTR)malloc(cbTarget);
232          memset (abTarget, 0x00, cbTarget);
233
234          BOOL fDefault = FALSE;
235          WideCharToMultiByte (g::CodePage, 0, (LPCWSTR)abSource, cbSource, abTarget, cbTarget, TEXT(" "), &fDefault);
236
237          rc = FormatFile (psz, abTarget);
238
239          free(abTarget);
240          }
241
242       free(abSource);
243       }
244
245    CloseHandle (hFile);
246    return rc;
247 }
248
249
250 LPTSTR FindFullPath (LPTSTR pszFormat, LPTSTR pszBaseName)
251 {
252    static TCHAR szOut[ MAX_PATH ];
253    lstrcpy (szOut, pszFormat);
254
255    LPTSTR pchSlash = NULL;
256    for (LPTSTR pch = szOut; *pch; ++pch)
257       if ((*pch == TEXT('\\')) || (*pch == TEXT('/')))
258          pchSlash = pch;
259    if (pchSlash)
260       lstrcpy (pchSlash, TEXT("\\"));
261    else
262       szOut[0] = TEXT('\0');
263    lstrcat (szOut, pszBaseName);
264    return szOut;
265 }
266
267
268 void main (int argc, char **argv)
269 {
270    int cFilesRequested = 0;
271
272    g::CodePage = CP_ACP;
273
274    for (--argc,++argv; argc; --argc,++argv)
275       {
276       if ((argv[0][0] == '-') || (argv[0][0] == '/'))
277          {
278          g::CodePage = atol(&argv[0][1]);
279          }
280       else // ((argv[0][0] != '-') && (argv[0][0] != '/'))
281          {
282          WIN32_FIND_DATA Data;
283
284          HANDLE hFind;
285          if ((hFind = FindFirstFile (argv[0], &Data)) == INVALID_HANDLE_VALUE)
286             {
287             printf ("file %s not found\n", argv[0]);
288             }
289          else
290             {
291             LPTSTR pszNames = NULL;
292
293             do {
294                if (!(Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
295                   mstrcat (&pszNames, TEXT('\0'), FindFullPath (argv[0], Data.cFileName));
296                } while (FindNextFile (hFind, &Data));
297
298             FindClose (hFind);
299
300             if (pszNames)
301                {
302                for (LPTSTR psz = pszNames; psz && *psz; psz += 1+lstrlen(psz))
303                   {
304                   printf ("translating %s into rtf...\n", psz);
305                   TranslateFile (psz);
306                   }
307                mstrfree (pszNames);
308                }
309             }
310
311          cFilesRequested++;
312          }
313       }
314
315    if (!cFilesRequested)
316       {
317       printf ("format : sgml2rtf filename {...}\r\n\r\n");
318       }
319
320    exit(0);
321 }
322