1 // WinSystem.cpp
2 // this file is part of Context Free
3 // ---------------------
4 // Copyright (C) 2005-2013 John Horigan - john@glyphic.com
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 //
20 // John Horigan can be contacted at john@glyphic.com or at
21 // John Horigan, 1209 Villa St., Mountain View, CA 94041-1123, USA
22 //
23 //
24 
25 #define _CRT_SECURE_NO_WARNINGS 1
26 
27 #include "WinSystem.h"
28 #include "cfdg.h"
29 #include <iostream>
30 #include <fstream>
31 #include <sstream>
32 #include <string>
33 #include <shlwapi.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <windows.h>
37 
38 
39 //map<const string, WinSystem*> WinSystem::PathMap;
40 std::map<const std::string, std::pair<std::string, std::string>> WinSystem::ExampleMap;
41 
42 void* WinSystem::MainWindow = nullptr;
43 
WinSystem(void * h)44 WinSystem::WinSystem(void* h)
45 :   mWindow(h)
46 {
47 }
48 
~WinSystem()49 WinSystem::~WinSystem()
50 {
51 }
52 
AddExample(const char * newName,const char * newText)53 void WinSystem::AddExample(const char* newName, const char* newText)
54 {
55     std::string name(newName);
56     bool v3 = true;
57 	auto pos = name.find("_v2");
58     if (pos != std::string::npos) {
59         name.erase(pos, 3);
60         v3 = false;
61     }
62     if (v3)
63         ExampleMap[name].first = newText;
64     else
65         ExampleMap[name].second = newText;
66 }
67 
updateInfo(const char * newName,const char * newText)68 bool WinSystem::updateInfo(const char* newName, const char* newText)
69 {
70     mName = newName;
71 
72     if (!strcmp(newText, mText.c_str()))
73         return false;
74 
75     mText = newText;
76     return true;
77 }
78 
message(const char * fmt,...)79 void WinSystem::message(const char* fmt, ...)
80 {
81     if (!mWindow) return;
82     va_list args;
83     va_start(args, fmt);
84     char cbuf[256];
85     _vsnprintf(cbuf, 255, fmt, args);
86     cbuf[255] = '\0';
87     va_end(args);
88 
89     char* buf = new char[strlen(cbuf) + 1];
90     strcpy(buf, cbuf);
91 
92     if (!::PostMessageW((HWND)mWindow, WM_USER_MESSAGE_UPDATE,(WPARAM)buf, NULL))
93         delete[] buf;
94 }
95 
syntaxError(const CfdgError & errLoc)96 void WinSystem::syntaxError(const CfdgError& errLoc)
97 {
98     if (!mWindow) return;
99     if (!errLoc.where.begin.filename || mName.compare(*(errLoc.where.begin.filename)) == 0) {
100         message("Error - <a href='#e:%d:%d:%d:%d'>%s</a>",
101                 errLoc.where.begin.line, errLoc.where.begin.column,
102                 errLoc.where.end.line, errLoc.where.end.column, errLoc.what());
103     } else {
104         message("Error in file %s at line %d:%d - %d:%d - %s", errLoc.where.end.filename->c_str(),
105                 errLoc.where.begin.line, errLoc.where.begin.column,
106                 errLoc.where.end.line, errLoc.where.end.column, errLoc.what());
107     }
108 }
109 
110 
error(bool errorOccurred)111 bool WinSystem::error(bool errorOccurred)
112 {
113     mErrorMode = mErrorMode || errorOccurred;
114     return mErrorMode;
115 }
116 
catastrophicError(const char * what)117 void WinSystem::catastrophicError(const char* what)
118 {
119     if (!MainWindow)
120         return;
121     wchar_t wbuf[32768];
122     if (::MultiByteToWideChar(CP_UTF8, 0, what, -1, wbuf, 32768))
123         (void)::MessageBoxW(NULL, wbuf, L"Unexpected error", MB_OK | MB_ICONEXCLAMATION);
124     else
125         (void)::MessageBoxW(NULL, L"", L"Unexpected error", MB_OK | MB_ICONEXCLAMATION);
126     ::PostMessageW((HWND)MainWindow, WM_CLOSE, NULL, NULL);
127     MainWindow = nullptr;   // Only do this once
128 }
129 
openFileForRead(const std::string & path)130 AbstractSystem::istr_ptr WinSystem::openFileForRead(const std::string& path)
131 {
132     auto filepos = path.rfind('\\');
133     filepos = filepos == std::string::npos ? 0 : filepos + 1;
134     std::string exname{ path, filepos };
135     auto exText = ExampleMap.find(exname);
136 
137     if (path == mName) {
138         return std::make_unique<std::stringstream>(mText);
139     } else if (exText != ExampleMap.end()) {
140         auto cfdg = cfdgVersion == 2 ? exText->second.second : exText->second.first;
141         return std::make_unique<std::stringstream>(cfdg, std::ios_base::in);
142     } else {
143         return std::make_unique<std::ifstream>(path.c_str(), std::ios::binary);
144     }
145 }
146 
stats(const Stats & s)147 void WinSystem::stats(const Stats& s)
148 {
149     if (!mWindow) return;
150     Stats* stat = new Stats(s);
151     if (!::PostMessageW((HWND)mWindow, WM_USER_STATUS_UPDATE,(WPARAM)stat, NULL))
152         delete stat;
153 }
154 
statusUpdate()155 void WinSystem::statusUpdate()
156 {
157     if (mWindow)
158         ::PostMessageW((HWND)mWindow, WM_USER_STATUS_UPDATE, NULL, NULL);
159 }
160 
orphan()161 void WinSystem::orphan()
162 {
163     mWindow = nullptr;
164     mName.clear();
165     mText.clear();
166 }
167