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