- Delete "smartpdf", it never worked and is outdated.
svn path=/trunk/; revision=33388
<xi:include href="screenshot/screenshot.rbuild" />
</directory>
- <!--
- <directory name="smartpdf">
- <xi:include href="smartpdf/fitz.rbuild" />
- <xi:include href="smartpdf/poppler.rbuild" />
- <xi:include href="smartpdf/smartpdf.rbuild" />
- </directory>
- -->
-
<directory name="sysutils">
<xi:include href="sysutils/sysutils.rbuild" />
</directory>
<xi:include href="templates/directory.rbuild" />
</directory>
- <directory name="winecalc">
- <xi:include href="winecalc/winecalc.rbuild" />
- </directory>
-
<directory name="winefile">
<xi:include href="winefile/winefile.rbuild" />
</directory>
+++ /dev/null
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-\f
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-
-#include "base_util.h"
-
-#include "WinUtil.hpp"
-
-#include "str_util.h"
-
-// TODO: exe name might be unicode so to support everything cmd or args
-// should be unicode or we can assume that cmd and args are utf8 and
-// convert them to utf16 and call CreateProcessW
-#define DONT_INHERIT_HANDLES FALSE
-
-// Given name of the command to exececute 'cmd', and its arguments 'args'
-// return WinProcess object that makes it easier to handle the process
-// Returns NULL if failed to create the process. Caller can use GetLastError()
-// for detailed error information.
-WinProcess * WinProcess::Create(const char* cmd, char* args)
-{
- UINT res;
- HANDLE stdOut = INVALID_HANDLE_VALUE;
- HANDLE stdErr = INVALID_HANDLE_VALUE;
- STARTUPINFOA siStartupInfo;
- PROCESS_INFORMATION piProcessInfo;
- SECURITY_ATTRIBUTES sa;
-
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = 0;
- sa.bInheritHandle = 1;
-
- memzero(&siStartupInfo, sizeof(siStartupInfo));
- memzero(&piProcessInfo, sizeof(piProcessInfo));
- siStartupInfo.cb = sizeof(siStartupInfo);
-
- char stdoutTempName[MAX_PATH] = {0};
- char stderrTempName[MAX_PATH] = {0};
- char *stdoutTempNameCopy = NULL;
- char *stderrTempNameCopy = NULL;
-
- char buf[MAX_PATH] = {0};
- int len = GetTempPathA(sizeof(buf), buf);
- assert(len < sizeof(buf));
- // create temporary files for capturing stdout and stderr or the command
- res = GetTempFileNameA(buf, "stdout", 0, stdoutTempName);
- if (0 == res)
- goto Error;
-
- res = GetTempFileNameA(buf, "stderr", 0, stderrTempName);
- if (0 == res)
- goto Error;
-
- stdoutTempNameCopy = str_dup(stdoutTempName);
- stderrTempNameCopy = str_dup(stderrTempName);
-
- stdOut = CreateFileA(stdoutTempNameCopy,
- GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_WRITE|FILE_SHARE_READ,
- &sa, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
- if (INVALID_HANDLE_VALUE == stdOut)
- goto Error;
-
- stdErr = CreateFileA(stderrTempNameCopy,
- GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_WRITE|FILE_SHARE_READ,
- &sa, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
- if (INVALID_HANDLE_VALUE == stdErr)
- goto Error;
-
- siStartupInfo.hStdOutput = stdOut;
- siStartupInfo.hStdError = stdErr;
-
- BOOL ok = CreateProcessA(cmd, args, NULL, NULL, DONT_INHERIT_HANDLES,
- CREATE_DEFAULT_ERROR_MODE, NULL /*env*/, NULL /*curr dir*/,
- &siStartupInfo, &piProcessInfo);
-
- if (!ok)
- goto Error;
-
- // TODO: pass stdoutTempNameCopy and stderrTempNameCopy so upon
- // WinProcess destruction the files can be deleted and their memory freed
- WinProcess *wp = new WinProcess(&piProcessInfo);
- return wp;
-
-Error:
- if (INVALID_HANDLE_VALUE != stdOut) {
- CloseHandle(stdOut);
- }
-
- if (INVALID_HANDLE_VALUE != stdErr) {
- CloseHandle(stdErr);
- }
-
- if (stdoutTempName[0]) {
- // TODO: delete stdoutTempName
- }
- if (stderrTempName[0]) {
- // TODO: delete stderrTempName
- }
- free(stdoutTempNameCopy);
- free(stderrTempNameCopy);
- return NULL;
-}
-
-WinProcess::WinProcess(PROCESS_INFORMATION *pi)
-{
- memcpy(&m_processInfo, pi, sizeof(PROCESS_INFORMATION));
-}
-
-
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef WINUTIL_HPP__
-#define WINUTIL_HPP__
-
-class WinProcess {
-public:
- static WinProcess* Create(const char *cmd, char *args="");
-
-private:
- WinProcess(PROCESS_INFORMATION *); // we don't want just anyone to make us
- PROCESS_INFORMATION m_processInfo;
-};
-#endif
-
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "base_util.h"
-
-void swap_int(int *one, int *two)
-{
- int tmp = *one;
- *one = *two;
- *two = tmp;
-}
-
-void swap_double(double *one, double *two)
-{
- double tmp = *one;
- *one = *two;
- *two = tmp;
-}
-
-int MinInt(int one, int two)
-{
- if (one < two)
- return one;
- else
- return two;
-}
-
-void memzero(void *data, size_t len)
-{
- memset(data, 0, len);
-}
-
-void *zmalloc(size_t len)
-{
- void *data = malloc(len);
- if (data)
- memzero(data, len);
- return data;
-}
-
-/* TODO: probably should move to some other file and change name to
- sleep_milliseconds */
-void sleep_milliseconds(int milliseconds)
-{
-#ifdef WIN32
- Sleep((DWORD)milliseconds);
-#else
- struct timespec tv;
- int secs, nanosecs;
- secs = milliseconds / 1000;
- nanosecs = (milliseconds - (secs * 1000)) * 1000;
- tv.tv_sec = (time_t) secs;
- tv.tv_nsec = (long) nanosecs;
- while (1)
- {
- int rval = nanosleep(&tv, &tv);
- if (rval == 0)
- /* Completed the entire sleep time; all done. */
- return;
- else if (errno == EINTR)
- /* Interrupted by a signal. Try again. */
- continue;
- else
- /* Some other error; bail out. */
- return;
- }
- return;
-#endif
-}
-
-/* milli-second timer */
-#ifdef _WIN32
-void ms_timer_start(ms_timer *timer)
-{
- assert(timer);
- if (!timer)
- return;
- QueryPerformanceCounter(&timer->start);
-}
-void ms_timer_stop(ms_timer *timer)
-{
- assert(timer);
- if (!timer)
- return;
- QueryPerformanceCounter(&timer->end);
-}
-
-double ms_timer_time_in_ms(ms_timer *timer)
-{
- LARGE_INTEGER freq;
- double time_in_secs;
- QueryPerformanceFrequency(&freq);
- time_in_secs = (double)(timer->end.QuadPart-timer->start.QuadPart)/(double)freq.QuadPart;
- return time_in_secs * 1000.0;
-}
-#else
-typedef struct ms_timer {
- struct timeval start;
- struct timeval end;
-} ms_timer;
-
-void ms_timer_start(ms_timer *timer)
-{
- assert(timer);
- if (!timer)
- return;
- gettimeofday(&timer->start, NULL);
-}
-
-void ms_timer_stop(ms_timer *timer)
-{
- assert(timer);
- if (!timer)
- return;
- gettimeofday(&timer->end, NULL);
-}
-
-double ms_timer_time_in_ms(ms_timer *timer)
-{
- double timeInMs;
- time_t seconds;
- int usecs;
-
- assert(timer);
- if (!timer)
- return 0.0;
- /* TODO: this logic needs to be verified */
- seconds = timer->end.tv_sec - timer->start.tv_sec;
- usecs = timer->end.tv_usec - timer->start.tv_usec;
- if (usecs < 0) {
- --seconds;
- usecs += 1000000;
- }
- timeInMs = (double)seconds*(double)1000.0 + (double)usecs/(double)1000.0;
- return timeInMs;
-}
-#endif
-
-
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef BASE_UTIL_H_
-#define BASE_UTIL_H_
-
-#ifdef _UNICODE
-#ifndef UNICODE
-#define UNICODE
-#endif
-#endif
-
-#ifdef UNICODE
-#ifndef _UNICODE
-#define _UNICODE
-#endif
-#endif
-
-/* It seems that Visual C defines WIN32 for Windows code but _WINDOWS for WINCE projects,
- so I'll make sure to set WIN32 always*/
-#ifdef _WINDOWS
- #ifndef WIN32
- #define WIN32 1
- #endif
- #ifndef _WIN32
- #define _WIN32 1
- #endif
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#include <tchar.h>
-#else
-#include <sys/time.h> // for timeval
-#endif
-
-/* Few most common includes for C stdlib */
-#include <assert.h>
-#include <stdio.h>
-
-#include <wchar.h>
-#include <string.h>
-
-#include <stdlib.h>
-#include <malloc.h>
-
-// TODO: does it need to be __GNUC__ only? I think it was done for mingw
-#ifdef __GNUC__
-#include <stdarg.h>
-#endif
-
-#ifndef TRUE
-#define TRUE (1)
-#endif
-
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-#ifdef _WIN32
- #ifndef __GNUC__
- typedef unsigned int uint32_t;
- #endif
- #ifndef _T
- #define _T TEXT
- #endif
-#else
- #define _T(x) x
- /* TODO: if _UNICODE, it should be different */
- #define TEXT(x) x
-#endif
-
-/* compile-time assert */
-#ifndef CASSERT
- #define CASSERT( exp, name ) typedef int dummy##name [ (exp ) ? 1 : -1 ];
-#endif
-
-/* Ugly name but the whole point is to make things shorter. */
-#define SA(struct_name) (struct_name *)malloc(sizeof(struct_name))
-#define SAZ(struct_name) (struct_name *)zmalloc(sizeof(struct_name))
-
-typedef long long int64;
-
-CASSERT( sizeof(int64)==8, int64_is_8_bytes )
-
-#define dimof(X) (sizeof(X)/sizeof((X)[0]))
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct ms_timer {
-#ifdef _WIN32
- LARGE_INTEGER start;
- LARGE_INTEGER end;
-#else
- struct timeval start;
- struct timeval end;
-#endif
-} ms_timer;
-
-#ifdef _WIN32
- void win32_dbg_out(const char *format, ...);
- void win32_dbg_out_hex(const char *dsc, const unsigned char *data, int dataLen);
-#endif
-
-/* TODO: consider using standard C macros for SWAP and MIN */
-void swap_int(int *one, int *two);
-void swap_double(double *one, double *two);
-int MinInt(int one, int two);
-
-void memzero(void *data, size_t len);
-void * zmalloc(size_t size);
-
-void sleep_milliseconds(int milliseconds);
-
-void ms_timer_start(ms_timer *timer);
-void ms_timer_stop(ms_timer *timer);
-double ms_timer_time_in_ms(ms_timer *timer);
-
-#define LIST_REVERSE_FUNC_PROTO(func_name, TYPE) \
-void func_name(TYPE **root)
-
-#define LIST_REVERSE_FUNC(func_name, TYPE) \
-void func_name(TYPE **root) \
-{ \
- TYPE * cur; \
- TYPE * next; \
- TYPE * new_first = NULL; \
-\
- if (!root) \
- return; \
-\
- cur = *root; \
- while (cur) { \
- next = cur->next; \
- cur->next = new_first; \
- new_first = cur; \
- cur = next; \
- } \
- *root = new_first; \
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#ifdef __cplusplus
-class MsTimer {
-public:
- MsTimer() { ms_timer_start(&timer); }
- void start(void) { ms_timer_start(&timer); }
- void stop(void) { ms_timer_stop(&timer); }
- double timeInMs(void) { return ms_timer_time_in_ms(&timer); }
-private:
- ms_timer timer;
-};
-#endif
-
-#endif
+++ /dev/null
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common_unit_tests", "common_unit_tests.vcproj", "{35EC4096-521D-44D0-B693-2BF11B85B275}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {35EC4096-521D-44D0-B693-2BF11B85B275}.Debug|Win32.ActiveCfg = Debug|Win32
- {35EC4096-521D-44D0-B693-2BF11B85B275}.Debug|Win32.Build.0 = Debug|Win32
- {35EC4096-521D-44D0-B693-2BF11B85B275}.Release|Win32.ActiveCfg = Release|Win32
- {35EC4096-521D-44D0-B693-2BF11B85B275}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="8.00"
- Name="common_unit_tests"
- ProjectGUID="{35EC4096-521D-44D0-B693-2BF11B85B275}"
- RootNamespace="common_unit_tests"
- Keyword="Win32Proj"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;DEBUG;_WIN32"
- MinimalRebuild="true"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="4"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32"
- RuntimeLibrary="2"
- UsePrecompiledHeader="0"
- WarningLevel="3"
- Detect64BitPortabilityProblems="true"
- DebugInformationFormat="3"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLinkerTool"
- LinkIncremental="2"
- GenerateDebugInformation="true"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCManifestTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCAppVerifierTool"
- />
- <Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath=".\base_util.h"
- >
- </File>
- <File
- RelativePath=".\file_util.h"
- >
- </File>
- <File
- RelativePath=".\netstr.h"
- >
- </File>
- <File
- RelativePath=".\prefs.h"
- >
- </File>
- <File
- RelativePath=".\str_util.h"
- >
- </File>
- <File
- RelativePath=".\win_util.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
- UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
- >
- </Filter>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath=".\base_util.c"
- >
- </File>
- <File
- RelativePath=".\file_util.c"
- >
- </File>
- <File
- RelativePath=".\netstr.c"
- >
- </File>
- <File
- RelativePath=".\prefs.c"
- >
- </File>
- <File
- RelativePath=".\str_util.c"
- >
- </File>
- <File
- RelativePath=".\str_util_test.c"
- >
- </File>
- <File
- RelativePath=".\unit_tests_all.c"
- >
- </File>
- <File
- RelativePath=".\win_util.c"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+++ /dev/null
-/****************************************************************************
- *
- * Dynamic strings
- ****************************************************************************/
-
-/*
- * tcl.h --
- *
- * This header file describes the externally-visible facilities
- * of the Tcl interpreter.
- *
- * Copyright (c) 1987-1994 The Regents of the University of California.
- * Copyright (c) 1994-1996 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39
- */
-
-
-#include "dstring.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include "str_strsafe.h"
-
-/*
- *----------------------------------------------------------------------
- *
- * DStringInit --
- *
- * Initializes a dynamic string, discarding any previous contents
- * of the string (DStringFree should have been called already
- * if the dynamic string was previously in use).
- *
- * Results:
- * None.
- *
- * Side effects:
- * The dynamic string is initialized to be empty.
- *
- *----------------------------------------------------------------------
- */
-
-void
-DStringInit(DString* pDs)
-{
- pDs->pString = pDs->staticSpace;
- pDs->length = 0;
- pDs->spaceAvl = kDstringStaticSize;
- pDs->staticSpace[0] = 0;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * DStringAppend --
- *
- * Append more characters to the current value of a dynamic string.
- *
- * Results:
- * The return value is a pointer to the dynamic string's new value.
- *
- * Side effects:
- * Length bytes from string (or all of string if length is less
- * than zero) are added to the current value of the string. Memory
- * gets reallocated if needed to accomodate the string's new size.
- *
- *----------------------------------------------------------------------
- */
-
-char *
-DStringAppend(DString *pDs,
- const char* string,
- int length)
-{
- int newSize;
- char* newString;
- char* dst;
- const char* end;
-
- if (length < 0) {
- length = strlen(string);
- }
- newSize = length + pDs->length;
-
- /*
- * Allocate a larger buffer for the string if the current one isn't
- * large enough. Allocate extra space in the new buffer so that there
- * will be room to grow before we have to allocate again.
- */
-
- if (newSize >= pDs->spaceAvl) {
- pDs->spaceAvl = newSize*2;
- newString = (char *) malloc((unsigned) pDs->spaceAvl);
- memcpy((void *)newString, (void *) pDs->pString,
- (size_t) pDs->length);
- if (pDs->pString != pDs->staticSpace) {
- free(pDs->pString);
- }
- pDs->pString = newString;
- }
-
- /*
- * Copy the new string into the buffer at the end of the old
- * one.
- */
-
- for (dst = pDs->pString + pDs->length, end = string+length;
- string < end; string++, dst++) {
- *dst = *string;
- }
- *dst = 0;
- pDs->length += length;
- return pDs->pString;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * DStringSetLength --
- *
- * Change the length of a dynamic string. This can cause the
- * string to either grow or shrink, depending on the value of
- * length.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The length of pDsis changed to length and a null byte is
- * stored at that position in the string. If length is larger
- * than the space allocated for pDs, then a panic occurs.
- *
- *----------------------------------------------------------------------
- */
-
-void
-DStringSetLength(DString* pDs,
- int length)
-{
- if (length < 0) {
- length = 0;
- }
- if (length >= pDs->spaceAvl) {
- char *newString;
-
- pDs->spaceAvl = length+1;
- newString = (char *) malloc((unsigned) pDs->spaceAvl);
-
- /*
- * SPECIAL NOTE: must use memcpy, not strcpy, to copy the string
- * to a larger buffer, since there may be embedded NULLs in the
- * string in some cases.
- */
-
- memcpy((void *) newString, (void*) pDs->pString,
- (size_t) pDs->length);
- if (pDs->pString != pDs->staticSpace) {
- free(pDs->pString);
- }
- pDs->pString = newString;
- }
- pDs->length = length;
- pDs->pString[length] = 0;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * DStringFree --
- *
- * Frees up any memory allocated for the dynamic string and
- * reinitializes the string to an empty state.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The previous contents of the dynamic string are lost, and
- * the new value is an empty string.
- *
- *----------------------------------------------------------------------
- */
-
-void
-DStringFree(DString* pDs)
-{
- if (pDs->pString != pDs->staticSpace) {
- free(pDs->pString);
- }
- pDs->pString = pDs->staticSpace;
- pDs->length = 0;
- pDs->spaceAvl = kDstringStaticSize;
- pDs->staticSpace[0] = 0;
-}
-
-/*
- * DStringSprintf --
- *
- * Append a formatted string to a dstring
- */
-
-void
-DStringSprintf(DString* pDs,
- const char* pFormat,
- ...)
-{
-#ifdef _WIN32
- HRESULT hr;
- va_list args;
- char message[256];
- char * buf;
- size_t bufCchSize;
- char * result = NULL;
-
- buf = &(message[0]);
- bufCchSize = sizeof(message);
-
- va_start(args, pFormat);
- for (;;)
- {
- /* TODO: this only works on windows with recent C library */
- hr = StringCchVPrintfA(buf, bufCchSize, pFormat, args);
- if (S_OK == hr)
- break;
- if (STRSAFE_E_INSUFFICIENT_BUFFER != hr)
- {
- /* any error other than buffer not big enough:
- a) should not happen
- b) means we give up */
- goto Error;
- }
- /* we have to make the buffer bigger. The algorithm used to calculate
- the new size is arbitrary (aka. educated guess) */
- if (buf != &(message[0]))
- free(buf);
- if (bufCchSize < 4*1024)
- bufCchSize += bufCchSize;
- else
- bufCchSize += 1024;
- buf = (char *)malloc(bufCchSize*sizeof(char));
- if (NULL == buf)
- goto Error;
- }
- va_end(args);
-
- DStringAppend(pDs, buf, -1);
-Error:
- if (buf != &(message[0]))
- free((void*)buf);
- return;
-#else
- va_list args;
- char* pBuffer;
- int len;
-
- va_start(args, pFormat);
- len = vasprintf(&pBuffer, pFormat, args);
- DStringAppend(pDs, pBuffer, len);
- free(pBuffer);
- va_end(args);
-#endif
-}
-
-/****************************************************************************
- * DStringAppendLowerCase --
- *
- * Append text to a dstring lowercased
- */
-
-char*
-DStringAppendLowerCase(DString* pDs,
- const char* string,
- int length)
-{
- int newSize;
- char* newString;
- char* dst;
- const char* end;
-
- if (length < 0) {
- length = strlen(string);
- }
- newSize = length + pDs->length;
-
- /*
- * Allocate a larger buffer for the string if the current one isn't
- * large enough. Allocate extra space in the new buffer so that there
- * will be room to grow before we have to allocate again.
- */
-
- if (newSize >= pDs->spaceAvl) {
- pDs->spaceAvl = newSize*2;
- newString = (char *) malloc((unsigned) pDs->spaceAvl);
- memcpy((void *)newString, (void *) pDs->pString,
- (size_t) pDs->length);
- if (pDs->pString != pDs->staticSpace) {
- free(pDs->pString);
- }
- pDs->pString = newString;
- }
-
- /*
- * Copy the new string into the buffer at the end of the old
- * one.
- */
-
- for (dst = pDs->pString + pDs->length, end = string+length;
- string < end; string++, dst++) {
- *dst = tolower(*string);
- }
- *dst = 0;
- pDs->length += length;
- return pDs->pString;
-}
+++ /dev/null
-/****************************************************************************
- * Dynamic strings
- ****************************************************************************/
-
-/*
- * tcl.h --
- *
- * This header file describes the externally-visible facilities
- * of the Tcl interpreter.
- *
- * Copyright (c) 1987-1994 The Regents of the University of California.
- * Copyright (c) 1994-1996 Sun Microsystems, Inc.
- *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- *
- * SCCS: @(#) tcl.h 1.283 96/10/02 17:17:39
- */
-#ifndef DSTRING_H
-#define DSTRING_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#define kDstringStaticSize 200
-
-typedef struct DString {
- char *pString; /* Points to beginning of string: either
- * staticSpace below or a malloc'ed array. */
- int length; /* Number of non-NULL characters in the
- * string. */
- int spaceAvl; /* Total number of bytes available for the
- * string and its terminating NULL char. */
- char staticSpace[kDstringStaticSize];
- /* Space to use in common case where string
- * is small. */
-} DString;
-
-#define DStringLength(dsPtr) ((dsPtr)->length)
-#define DStringValue(dsPtr) ((dsPtr)->pString)
-#define DStringTrunc DStringSetLength
-
-char*
-DStringAppend(DString* dsPtr,
- const char* string,
- int length);
-
-void
-DStringFree(DString* dsPtr);
-
-void
-DStringInit(DString* dsPtr);
-
-void
-DStringSetLength(DString* dsPtr,
- int length);
-
-void
-DStringSprintf(DString* pDs,
- const char* pFormat,
- ...);
-char*
-DStringAppendLowerCase(DString* pDs,
- const char* pIn,
- int length);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "base_util.h"
-#include "file_util.h"
-
-#include "str_util.h"
-#include "strlist_util.h"
-
-char *FilePath_ConcatA(const char *path, const char *name)
-{
- assert(path && name);
- if (!path || !name) return NULL;
-
- if (str_endswith(path, DIR_SEP_STR))
- return str_cat(path, name);
- else
- return str_cat3(path, DIR_SEP_STR, name);
-}
-
-const char *FilePath_GetBaseName(const char *path)
-{
- const char *fileBaseName = (const char*)strrchr(path, DIR_SEP_CHAR);
- if (NULL == fileBaseName)
- fileBaseName = path;
- else
- ++fileBaseName;
- return fileBaseName;
-}
-
-char *FilePath_GetDir(const char *path)
-{
- char *lastSep;
- char *dir = str_dup(path);
- if (!dir) return NULL;
- lastSep = (char*)strrchr(dir, DIR_SEP_CHAR);
- if (NULL != lastSep)
- *lastSep = 0;
- return dir;
-}
-
-/* TODO: handle TCHAR (UNICODE) properly by converting to path to unicode
- if UNICODE or _UNICODE symbols are defined */
-/* Start iteration of all files 'path'. 'path' should be a directory
- name but doesn't have to end with "\" (we append it if it's missing)
- Retuns NULL if there was an error.
- When no longer needed, the result should be deleted with
- 'DirIter_Delete'.
-*/
-DirIterState *DirIter_New(const char *path)
-{
- DirIterState *state;
-
- assert(path);
-
- if (!path)
- return NULL;
-
- state = SA(DirIterState);
- if (!state)
- return NULL;
-
- /* TODO: made state->cleanPath cannonical */
- state->cleanPath = str_dup(path);
- state->iterPath = FilePath_ConcatA(path, "*");
- if (!state->cleanPath || !state->iterPath) {
- DirIter_Delete(state);
- return NULL;
- }
- state->dir = INVALID_HANDLE_VALUE;
- return state;
-}
-
-/* Get information about next file in a directory.
- Returns FALSE on end of iteration (or error). */
-BOOL DirIter_Next(DirIterState *s)
-{
- BOOL found;
-
- if (INVALID_HANDLE_VALUE == s->dir) {
- s->dir = FindFirstFileA(s->iterPath, &(s->fileInfo));
- if (INVALID_HANDLE_VALUE == s->dir)
- return FALSE;
- goto CheckFile;
- }
-
- for(;;) {
- found = FindNextFileA(s->dir, &(s->fileInfo));
- if (!found)
- return FALSE;
- else
-CheckFile:
- return TRUE;
- }
-}
-
-/* Free memory associated with 'state' */
-void DirIter_Delete(DirIterState *state)
-{
- if (state) {
- free(state->cleanPath);
- free(state->iterPath);
- }
- free(state);
-}
-
-static FileList *FileList_New(char *dir)
-{
- FileList *fl;
-
- assert(dir);
-
- fl = SAZ(FileList);
- if (!fl)
- return NULL;
- fl->dirName = str_dup(dir);
- if (!fl->dirName) {
- free((void*)fl);
- return NULL;
- }
- return fl;
-}
-
-static BOOL FileList_InsertFileInfo(FileList *fl, FileInfo *fi)
-{
- int real_count;
- FileInfo *last_fi;
-
- assert(fl);
- if (!fl)
- return FALSE;
- assert(fi);
- if (!fi)
- return FALSE;
- /* TODO: use scheme where we also track of the last node, so that
- insert is O(1) and not O(n) */
- assert(!fi->next);
- fi->next = NULL;
- if (!fl->first) {
- assert(0 == fl->filesCount);
- fl->first = fi;
- fl->filesCount = 1;
- return TRUE;
- }
-
- last_fi = fl->first;
- assert(last_fi);
- real_count = 1;
- while (last_fi->next) {
- ++real_count;
- last_fi = last_fi->next;
- }
-
- assert(real_count == fl->filesCount);
- last_fi->next = fi;
- ++fl->filesCount;
- return TRUE;
-}
-
-void FileInfo_Delete(FileInfo *fi)
-{
- if (!fi) return;
- free(fi->name);
- free(fi->path);
- free(fi);
-}
-
-static FileInfo *FileInfo_New(char *path, char *name, int64 size, DWORD attr, FILETIME *modificationTime)
-{
- FileInfo *fi;
-
- assert(name);
- if (!name)
- return NULL;
-
- assert(modificationTime);
- if (!modificationTime)
- return NULL;
-
- fi = SAZ(FileInfo);
- if (!fi)
- return NULL;
-
- fi->name = str_dup(name);
- fi->path = str_dup(path);
- if (!fi->name || !fi->path) {
- FileInfo_Delete(fi);
- return NULL;
- }
-
- fi->size = size;
- fi->attr = attr;
- fi->modificationTime = *modificationTime;
- return fi;
-}
-
-static FileInfo* FileInfo_FromDirIterState(DirIterState *state)
-{
- FileInfo * fi;
- WIN32_FIND_DATAA *fd;
- char * fileName;
- int64 size;
- char * filePath;
-
- assert(state);
- if (!state) return NULL;
-
- fd = &state->fileInfo;
- size = fd->nFileSizeHigh;
- size = size >> 32;
- size += fd->nFileSizeLow;
- /* TODO: handle UNICODE */
- fileName = fd->cFileName;
- filePath = FilePath_ConcatA(state->cleanPath, fileName);
- fi = FileInfo_New(filePath, fileName, size, fd->dwFileAttributes, &fd->ftLastWriteTime);
- return fi;
-}
-
-BOOL FileInfo_IsFile(FileInfo *fi)
-{
- DWORD attr;
- assert(fi);
- if (!fi) return
-FALSE;
- attr = fi->attr;
-
- if (!(attr & FILE_ATTRIBUTE_DIRECTORY))
- return TRUE;
- return FALSE;
-}
-
-int FileInfo_IsDir(FileInfo *fi)
-{
- DWORD attr;
- assert(fi);
- if (!fi) return
-FALSE;
- attr = fi->attr;
-
- if (attr & FILE_ATTRIBUTE_DIRECTORY)
- return TRUE;
- return FALSE;
-}
-
-static int FileList_Append(char *path, FileList *fl, int (*filter)(FileInfo *))
-{
- FileInfo * fi;
- DirIterState * state;
- int shouldInsert;
-
- if (!path || !fl)
- return 0;
-
- state = DirIter_New(path);
- if (!state) {
- return 0;
- }
-
- /* TODO: handle errors from DirIter_Next */
- while (DirIter_Next(state)) {
- fi = FileInfo_FromDirIterState(state);
- if (!fi) {
- DirIter_Delete(state);
- return 0;
- }
- if (fi) {
- shouldInsert = 1;
- if (filter && !(*filter)(fi))
- shouldInsert = 0;
- if (shouldInsert)
- FileList_InsertFileInfo(fl, fi);
- }
- }
- DirIter_Delete(state);
- return 1;
-}
-
-/* Return a list of files/directories in a 'path'. Use filter function
- to filter out files that should not get included (return 0 from the function
- to exclude it from the list.
- Returns NULL in case of an error.
- Use FileList_Delete() to free up all memory associated with this data.
- Doesn't recurse into subdirectores, use FileList_GetRecursive for that. */
-/* TODO: 'filter' needs to be implemented. */
-/* TODO: add 'filterRegexp' argument that would allow filtering via regular
- expression */
-FileList *FileList_Get(char* path, int (*filter)(FileInfo *))
-{
- FileList * fl;
- int ok;
-
- if (!path)
- return NULL;
-
- /* TODO: should I expand "." ? */
- fl = FileList_New(path);
- if (!fl)
- return NULL;
-
- ok = FileList_Append(path, fl, filter);
- if (!ok) {
- FileList_Delete(fl);
- return NULL;
- }
- return fl;
-}
-
-/* Like FileList_Get() except recurses into sub-directories */
-/* TODO: 'filter' needs to be implemented. */
-/* TODO: add 'filterRegexp' argument that would allow filtering via regular
- expression */
-FileList *FileList_GetRecursive(char* path, int (*filter)(FileInfo *))
-{
- StrList *toVisit = NULL;
- FileList *fl = NULL;
- assert(0);
- /* TODO: clearly, implement */
- return NULL;
-}
-
-void FileList_Delete(FileList *fl)
-{
- FileInfo *fi;
- FileInfo *fi_next;
- if (!fl)
- return;
- fi = fl->first;
- while (fi) {
- fi_next = fi->next;
- FileInfo_Delete(fi);
- fi = fi_next;
- }
- free((void*)fl->dirName);
- free((void*)fl);
-}
-
-int FileList_Len(FileList *fl)
-{
- return fl->filesCount;
-}
-
-FileInfo *FileList_GetFileInfo(FileList *fl, int file_no)
-{
- FileInfo *fi;
- if (!fl)
- return NULL;
- if (file_no >= fl->filesCount)
- return NULL;
- fi = fl->first;
- while (file_no > 0) {
- assert(fi->next);
- if (!fi->next)
- return NULL;
- fi = fi->next;
- --file_no;
- }
- return fi;
-}
-
-#ifdef _WIN32
-size_t file_size_get(const char *file_path)
-{
- int fOk;
- WIN32_FILE_ATTRIBUTE_DATA fileInfo;
-
- if (NULL == file_path)
- return INVALID_FILE_SIZE;
-
- fOk = GetFileAttributesExA(file_path, GetFileExInfoStandard, (void*)&fileInfo);
- if (!fOk)
- return INVALID_FILE_SIZE;
- return (size_t)fileInfo.nFileSizeLow;
-}
-#else
-#include <sys/types.h>
-#include <sys/stat.h>
-
-size_t file_size_get(const char *file_path)
-{
- struct stat stat_buf;
- int res;
- unsigned long size;
- if (NULL == file_path)
- return INVALID_FILE_SIZE;
- res = stat(file_path, &stat_buf);
- if (0 != res)
- return INVALID_FILE_SIZE;
- size = (size_t)stat_buf.st_size;
- return size;
-}
-#endif
-
-#ifdef _WIN32
-char *file_read_all(const char *file_path, size_t *file_size_out)
-{
- DWORD size, size_read;
- HANDLE h;
- char * data = NULL;
- int f_ok;
-
- h = CreateFileA(file_path, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE)
- return NULL;
-
- size = GetFileSize(h, NULL);
- if (-1 == size)
- goto Exit;
-
- /* allocate one byte more and 0-terminate just in case it's a text
- file we'll want to treat as C string. Doesn't hurt for binary
- files */
- data = (char*)malloc(size + 1);
- if (!data)
- goto Exit;
- data[size] = 0;
-
- f_ok = ReadFile(h, data, size, &size_read, NULL);
- if (!f_ok) {
- free(data);
- data = NULL;
- }
- *file_size_out = (size_t)size;
-Exit:
- CloseHandle(h);
- return data;
-}
-#else
-/* TODO: change unsinged long to int64 or size_t */
-char *file_read_all(const char *file_path, size_t *file_size_out)
-{
- FILE *fp = NULL;
- char *data = NULL;
- size_t read;
-
- size_t file_size = file_size_get(file_path);
- if (INVALID_FILE_SIZE == file_size)
- return NULL;
-
- data = (char*)malloc(file_size + 1);
- if (!data)
- goto Exit;
- data[file_size] = 0;
-
- fp = fopen(file_path, "rb");
- if (!fp)
- goto Error;
-
- read = fread((void*)data, 1, file_size, fp);
- if (ferror(fp))
- goto Error;
- assert(read == file_size);
- if (read != file_size)
- goto Error;
- fclose(fp);
- return data;
-Error:
- if (fp)
- fclose(fp);
- free((void*)data);
- return NULL;
-}
-#endif
-
-#ifdef _WIN32
-BOOL write_to_file(const TCHAR *file_path, void *data, size_t data_len)
-{
- DWORD size;
- HANDLE h;
- BOOL f_ok;
-
- h = CreateFile(file_path, GENERIC_WRITE, FILE_SHARE_READ, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (h == INVALID_HANDLE_VALUE)
- return FALSE;
-
- f_ok = WriteFile(h, data, (DWORD)data_len, &size, NULL);
- assert(!f_ok || ((DWORD)data_len == size));
- CloseHandle(h);
- return f_ok;
-}
-#else
-// not supported
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef FILE_UTILS_H_
-#define FILE_UTILS_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct DirIterState {
- char * fileName;
- char * cleanPath;
- char * iterPath;
- WIN32_FIND_DATAA fileInfo;
- HANDLE dir;
-} DirIterState;
-
-typedef struct FileInfo {
- struct FileInfo *next;
- char * path; /* full path of the file e.g. c:\foo\bar.txt */
- char * name; /* just the name part e.g. bar.txt, points into 'path' */
- int64 size;
- FILETIME modificationTime;
- FILETIME accessTime;
- FILETIME createTime;
- DWORD attr;
- /* TODO: file attributes like file type etc. */
-} FileInfo;
-
-typedef struct FileList {
- FileInfo * first;
- char * dirName; /* directory where files lives e.g. c:\windows\ */
- int filesCount;
-} FileList;
-
-DirIterState * DirIter_New(const char *path);
-BOOL DirIter_Next(DirIterState *s);
-void DirIter_Delete(DirIterState *state);
-
-BOOL FileInfo_IsFile(FileInfo *fi);
-BOOL FileInfo_IsDir(FileInfo *fi);
-void FileInfo_Delete(FileInfo *fi);
-FileList * FileList_Get(char* path, int (*filter)(FileInfo *));
-FileList * FileList_GetRecursive(char* path, int (*filter)(FileInfo *));
-void FileList_Delete(FileList *fl);
-int FileList_Len(FileList *fl);
-FileInfo * FileList_GetFileInfo(FileList *fl, int file_no);
-
-const char * FilePath_GetBaseName(const char *path);
-char * FilePath_GetDir(const char *path);
-
-char * file_read_all(const char *file_path, size_t *file_size_out);
-size_t file_size_get(const char *file_path);
-BOOL write_to_file(const TCHAR *file_path, void *data, size_t data_len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "base_util.h"
-#include "geom_util.h"
-
-/* Return true if 'r1' and 'r2' intersect. Put the intersect area into
- 'rIntersectOut'.
- Return false if there is no intersection. */
-int RectI_Intersect(RectI *r1, RectI *r2, RectI *rIntersectOut)
-{
- int x1s, x1e, x2s, x2e;
- int y1s, y1e, y2s, y2e;
-
- int xIntersectS, xIntersectE;
- int yIntersectS, yIntersectE;
-
- assert(r1 && r2 && rIntersectOut);
- if (!r1 || !r2 || !rIntersectOut)
- return 0;
-
- x1s = r1->x;
- x2s = r2->x;
- x1e = x1s + r1->dx;
- x2e = x2s + r2->dx;
-
- /* { } visualizes r1 and | | visualizes r2 */
-
- /* problem is symmetric, so reduce the number of different cases by
- consistent ordering where r1 is always before r2 in axis-x */
- if (x2s < x1s) {
- swap_int(&x1s, &x2s);
- swap_int(&x1e, &x2e);
- }
-
- /* case of non-overlapping rectangles i.e.:
- { } | | */
- if (x2s > x1e)
- return 0;
-
- /* partially overlapped i.e.:
- { | } |
- and one inside the other i.e.:
- { | | } */
-
- assert(x2s >= x1s);
- assert(x2s <= x1e);
- xIntersectS = x2s;
- xIntersectE = MinInt(x1e, x2e);
- assert(xIntersectE >= xIntersectS);
-
- /* the logic for y is the same */
- y1s = r1->y;
- y2s = r2->y;
- y1e = y1s + r1->dy;
- y2e = y2s + r2->dy;
- if (y2s < y1s) {
- swap_int(&y1s, &y2s);
- swap_int(&y1e, &y2e);
- }
- if (y2s > y1e)
- return 0;
- assert(y2s >= y1s);
- assert(y2s <= y1e);
- yIntersectS = y2s;
- yIntersectE = MinInt(y1e, y2e);
-
- rIntersectOut->x = xIntersectS;
- rIntersectOut->y = yIntersectS;
- assert(xIntersectE >= xIntersectS);
- assert(yIntersectE >= yIntersectS);
- rIntersectOut->dx = xIntersectE - xIntersectS;
- rIntersectOut->dy = yIntersectE - yIntersectS;
- return 1;
-}
-
-void RectI_FromXY(RectI *rOut, int xs, int xe, int ys, int ye)
-{
- assert(rOut);
- if (!rOut)
- return;
- assert(xs <= xe);
- assert(ys <= ye);
- rOut->x = xs;
- rOut->y = ys;
- rOut->dx = xe - xs;
- rOut->dy = ye - ys;
-}
-
-void RectD_FromRectI(RectD *rOut, RectI *rIn)
-{
- rOut->x = (double)rIn->x;
- rOut->y = (double)rIn->y;
- rOut->dx = (double)rIn->dx;
- rOut->dy = (double)rIn->dy;
-}
-
-int intFromDouble (double d) {
- double i1 = (int) d;
- double i2 = i1 + 1;
-
- if (d - i1 < i2 - d)
- return i1;
- else
- return i2;
-}
-
-void RectI_FromRectD(RectI *rOut, RectD *rIn)
-{
- rOut->x = intFromDouble(rIn->x);
- rOut->y = intFromDouble(rIn->y);
- rOut->dx = intFromDouble(rIn->dx);
- rOut->dy = intFromDouble(rIn->dy);
-}
-
-void RectD_Copy(RectD *rOut, RectD *rIn) {
- rOut->x = (double)rIn->x;
- rOut->y = (double)rIn->y;
- rOut->dx = (double)rIn->dx;
- rOut->dy = (double)rIn->dy;
-}
-
-void RectD_FromXY(RectD *rOut, double xs, double xe, double ys, double ye)
-{
- assert(rOut);
- if (!rOut)
- return;
- if (xs > xe)
- swap_double(&xs, &xe);
- if (ys > ye)
- swap_double(&ys, &ye);
-
- rOut->x = xs;
- rOut->y = ys;
- rOut->dx = xe - xs;
- assert(rOut->dx >= 0.0);
- rOut->dy = ye - ys;
- assert(rOut->dy >= 0.0);
-}
-
-/* Return TRUE if point 'x'/'y' is inside rectangle 'r' */
-int RectI_Inside(RectI *r, int x, int y)
-{
- if (x < r->x)
- return FALSE;
- if (x > r->x + r->dx)
- return FALSE;
- if (y < r->y)
- return FALSE;
- if (y > r->y + r->dy)
- return FALSE;
- return TRUE;
-}
-
-#ifndef NDEBUG
-void RectI_AssertEqual(RectI *rIntersect, RectI *rExpected)
-{
- assert(rIntersect->x == rExpected->x);
- assert(rIntersect->y == rExpected->y);
- assert(rIntersect->dx == rExpected->dx);
- assert(rIntersect->dy == rExpected->dy);
-}
-
-void u_RectI_Intersect(void)
-{
- int i, dataLen;
- RectI r1, r2, rIntersect, rExpected, rExpectedSwaped;
- int doIntersect, doIntersectExpected;
-
- struct SRIData {
- int x1s, x1e, y1s, y1e;
- int x2s, x2e, y2s, y2e;
- int intersect;
- int i_xs, i_xe, i_ys, i_ye;
- } testData[] = {
- { 0,10, 0,10, 0,10, 0,10, 1, 0,10, 0,10 }, /* complete intersect */
- { 0,10, 0,10, 20,30,20,30, 0, 0, 0, 0, 0 }, /* no intersect */
- { 0,10, 0,10, 5,15, 0,10, 1, 5,10, 0,10 }, /* { | } | */
- { 0,10, 0,10, 5, 7, 0,10, 1, 5, 7, 0,10 }, /* { | | } */
-
- { 0,10, 0,10, 5, 7, 5, 7, 1, 5, 7, 5, 7 },
- { 0,10, 0,10, 5, 15,5,15, 1, 5,10, 5,10 },
- };
- dataLen = dimof(testData);
- for (i = 0; i < dataLen; i++) {
- struct SRIData *curr;
- curr = &(testData[i]);
- RectI_FromXY(&rExpected, curr->i_xs, curr->i_xe, curr->i_ys, curr->i_ye);
- RectI_FromXY(&rExpectedSwaped, curr->i_ys, curr->i_ye, curr->i_xs, curr->i_xe);
-
- RectI_FromXY(&r1, curr->x1s, curr->x1e, curr->y1s, curr->y1e);
- RectI_FromXY(&r2, curr->x2s, curr->x2e, curr->y2s, curr->y2e);
- doIntersectExpected = curr->intersect;
-
- doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
- assert(doIntersect == doIntersectExpected);
- if (doIntersect)
- RectI_AssertEqual(&rIntersect, &rExpected);
-
- /* if we swap rectangles, the results should be the same */
- RectI_FromXY(&r2, curr->x1s, curr->x1e, curr->y1s, curr->y1e);
- RectI_FromXY(&r1, curr->x2s, curr->x2e, curr->y2s, curr->y2e);
- doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
- assert(doIntersect == doIntersectExpected);
- if (doIntersect)
- RectI_AssertEqual(&rIntersect, &rExpected);
-
- /* if we swap x with y coordinates in a rectangle, results should be the same */
- RectI_FromXY(&r1, curr->y1s, curr->y1e, curr->x1s, curr->x1e);
- RectI_FromXY(&r2, curr->y2s, curr->y2e, curr->x2s, curr->x2e);
- doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
- assert(doIntersect == doIntersectExpected);
- if (doIntersect)
- RectI_AssertEqual(&rIntersect, &rExpectedSwaped);
-
- /* swap both rectangles and x with y, results should be the same */
- RectI_FromXY(&r2, curr->y1s, curr->y1e, curr->x1s, curr->x1e);
- RectI_FromXY(&r1, curr->y2s, curr->y2e, curr->x2s, curr->x2e);
- doIntersect = RectI_Intersect(&r1, &r2, &rIntersect);
- assert(doIntersect == doIntersectExpected);
- if (doIntersect)
- RectI_AssertEqual(&rIntersect, &rExpectedSwaped);
- }
-}
-#endif
-
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef GEOM_UTIL_H_
-#define GEOM_UTIL_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct RectI {
- int x, y;
- int dx, dy;
-} RectI;
-
-typedef struct RectD {
- double x,y;
- double dx,dy;
-} RectD;
-
-int RectI_Intersect(RectI *r1, RectI *r2, RectI *rIntersectOut);
-void RectI_FromXY(RectI *rOut, int xs, int xe, int ys, int ye);
-int RectI_Inside(RectI *r, int x, int y);
-void RectD_FromXY(RectD *rOut, double xs, double xe, double ys, double ye);
-void RectD_FromRectI(RectD *rOut, RectI *rIn);
-void RectI_FromRectD(RectI *rOut, RectD *rIn);
-void RectD_Copy(RectD *rOut, RectD *rIn);
-void u_RectI_Intersect(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-/* allow using from both C and C++ code */
-#ifdef __cplusplus
-class PointD {
-public:
- PointD() { x = 0; y = 0; }
- PointD(double _x, double _y) { x = _x; y = _y; }
- void set(double _x, double _y) { x = _x; y = _y; }
- double x;
- double y;
-};
-
-class SizeI {
-public:
- SizeI(int _dx, int _dy) { dx = _dx; dy = _dy; }
- void set(int _dx, int _dy) { dx = _dx; dy = _dy; }
- int dx;
- int dy;
-};
-
-class SizeD {
-public:
- SizeD(double dx, double dy) { m_dx = dx; m_dy = dy; }
- SizeD(int dx, int dy) { m_dx = (double)dx; m_dy = (double)dy; }
- SizeD(SizeI si) { m_dx = (double)si.dx; m_dy = (double)si.dy; }
- SizeD() { m_dx = 0; m_dy = 0; }
- int dxI() { return (int)m_dx; }
- int dyI() { return (int)m_dy; }
- double dx() { return m_dx; }
- double dy() { return m_dy; }
- void setDx(double dx) { m_dx = dx; }
- void setDy(double dy) { m_dy = dy; }
- SizeI size() { return SizeI((int)dx(), (int)dy()); } /* @note: int casts */
-private:
- double m_dx;
- double m_dy;
-};
-
-#endif
-
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "log_util.h"
-#include "str_util.h"
-
-/* Simple logging. 'slog' stands for "simple logging". I figured that 'log'
- is a very common name so used something else, but still short as a prefix
- for API names */
-
-/* TODO: slogfmt(const char *fmt, ...) */
-
-/* TODO: extend to more than one file, by keeping a list of file names */
-const TCHAR * g_cur_fileName = NULL;
-
-/* initialize logging system, should be called before any logging calls */
-BOOL slog_init(void)
-{
- /* do nothing yet */
- return TRUE;
-}
-
-/* deinitialize logging system. Should be called before the program quits */
-void slog_deinit(void)
-{
- slog_file_log_stop(NULL);
-}
-
-/* start logging to a file 'fileName'. From now on until slog_file_log_stop()
- all slog* logging will also go to a file. If a file of that name already
- exists, it'll overwrite it. */
-BOOL slog_file_log_start(const TCHAR *fileName)
-{
- if (!fileName) return FALSE;
- g_cur_fileName = tstr_dup(fileName);
- DeleteFile(fileName);
- return TRUE;
-}
-
-/* like 'slog_file_log_start' but will create a unique file based on 'fileName'.
- If a 'fileName' has extension, it'll try the first available
- '$file-$NNN.$ext' file (e.g. "my-app-log-000.txt") if 'fileName' is "my-app-log.txt"
- If there is no extension, it'll be '$file-$NNN' */
-int slog_file_log_unique_start(const TCHAR *fileName)
-{
- assert(0); /* not implemented */
- return FALSE;
-}
-
-void slog_file_log_stop(const TCHAR *fileName)
-{
- /* 'fileName' is currently unused. The idea is that it should match the
- name given to slog_file_log_start */
- if (g_cur_fileName) {
- free((void*)g_cur_fileName);
- g_cur_fileName = NULL;
- }
-}
-
-/* log 'txt' to all currently enabled loggers */
-void slog_str(const char *txt)
-{
- DWORD to_write_cb;
- DWORD written_cb;
- int f_ok;
- HANDLE fh;
-
- if (!txt) return;
-
- if (!g_cur_fileName) return;
-
- /* we're using this inefficient way of re-opening the file for each
- log so that we can also watch this file life using tail-like program */
- fh = CreateFile(g_cur_fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
- OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (INVALID_HANDLE_VALUE == fh)
- return;
- SetFilePointer(fh, 0, NULL, FILE_END);
- to_write_cb = (DWORD)strlen(txt);
- f_ok = WriteFile(fh, (void*)txt, to_write_cb, &written_cb, NULL);
- assert(f_ok && (written_cb == to_write_cb));
- CloseHandle(fh);
-}
-
-void slog_str_printf(const char *format, ...)
-{
- char * tmp;
- va_list args;
-
- va_start(args, format);
- tmp = str_printf_args(format, args);
- va_end(args);
- if (!tmp) return;
- slog_str(tmp);
- free(tmp);
-}
-
-static WCHAR* last_error_as_wstr(void)
-{
- WCHAR *msgBuf = NULL;
- WCHAR *copy;
- FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &msgBuf, 0, NULL);
- if (!msgBuf) return NULL;
- copy = wstr_dup(msgBuf);
- LocalFree(msgBuf);
- return copy;
-}
-
-void slog_last_error(const char *optional_prefix)
-{
- WCHAR *txt = last_error_as_wstr();
- if (!txt) return;
- slog_str(optional_prefix);
- slog_wstr_nl(txt);
- free(txt);
-}
-
-/* TODO: converting by casting isn't always correct but here we don't care much */
-char *wstr_to_str(const WCHAR *txt)
-{
- char *txt_copy, *tmp;
-
- if (!txt) return NULL;
-
- txt_copy = (char*)malloc(tstr_len(txt) + 1);
- if (!txt_copy) return NULL;
-
- tmp = txt_copy;
- while (*txt) {
- *tmp++ = (char)*txt++;
- }
- *tmp = 0;
- return txt_copy;
-}
-
-void slog_wstr(const WCHAR *txt)
-{
- char *txt_copy;
-
- txt_copy = wstr_to_str(txt);
- if (!txt_copy) return;
- slog_str(txt_copy);
- free(txt_copy);
-}
-
-/* log 'txt' to all currently enabled loggers and add newline */
-void slog_str_nl(const char *txt)
-{
- /* TODO: given the 'reopen the file each time' implementation of
- slgotxt, this should be optimized */
- slog_str(txt);
- slog_str("\n");
-}
-
-void slog_wstr_nl(const WCHAR *txt)
-{
- slog_wstr(txt);
- slog_wstr(_T("\n"));
-}
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef LOG_UTIL_H_
-#define LOG_UTIL_H_
-
-#include "base_util.h"
-#include "tstr_util.h"
-
-BOOL slog_init(void);
-void slog_deinit(void);
-BOOL slog_file_log_start(const TCHAR *fileName);
-void slog_file_log_stop(const TCHAR *fileName);
-void slog_str(const char *txt);
-void slog_str_printf(const char *format, ...);
-void slog_str_nl(const char *txt);
-
-void slog_last_error(const char *optional_prefix);
-
-void slog_wstr(const WCHAR *txt);
-void slog_wstr_nl(const WCHAR *txt);
-
-#endif
-
+++ /dev/null
-OUTDIR=obj-dummy
-CC=cl.exe
-
-VALID_TARGET=no
-
-!if "$(TARGET)"=="rel"
-OUTDIR=obj-win-rel
-CFLAGS = $(CFLAGS) /D "NDEBUG" /D "_SECURE_CSL=0" /MD /Ox
-LDFLAGS = $(LDFLAGS) /OPT:NOWIN98
-VALID_TARGET=yes
-!endif
-
-!if "$(TARGET)"=="rel-unicode"
-OUTDIR=obj-win-rel-unicode
-CFLAGS = $(CFLAGS) /D "NDEBUG" /D "_SECURE_CSL=0" /D "UNICODE" /MD /Ox
-LDFLAGS = $(LDFLAGS) /OPT:NOWIN98
-VALID_TARGET=yes
-!endif
-
-!if "$(TARGET)"=="dbg"
-OUTDIR=obj-win-dbg
-CFLAGS = $(CFLAGS) /D "_SECURE_CSL=0" /MDd /Od
-VALID_TARGET=yes
-!endif
-
-!if "$(TARGET)"=="dbg-unicode"
-OUTDIR=obj-win-dbg-unicode
-CFLAGS = $(CFLAGS) /D "_SECURE_CSL=0" /D "UNICODE" /MDd /Od
-VALID_TARGET=yes
-!endif
-
-O=$(OUTDIR)
-CFLAGS = $(CFLAGS) /nologo /c
-CFLAGS = $(CFLAGS) /D "WIN32" /D "_WIN32_WINNT=0x0500"
-CFLAGS = $(CFLAGS) /W3 /Zc:forScope /Zc:wchar_t /GR /Zi
-CFLAGS = $(CFLAGS) /I.
-
-LIBS = $(LIBS) kernel32.lib advapi32.lib comctl32.lib comdlg32.lib \
- shell32.lib user32.lib gdi32.lib
-
-LD = link.exe
-LDFLAGS = $(LDFLAGS) /nologo /DEBUG
-
-TEST_FILE_UTIL_OBJS=$(O)\base_util.obj $(O)\file_util.obj $(O)\geom_util.obj \
- $(O)\prefs_util.obj $(O)\netstr.obj $(O)\str_util.obj $(O)\WinUtil.obj \
- $(O)\win_util.obj $(O)\wstr_util.obj \
- $(O)\test_file_util.obj
-TEST_FILE_UTIL_EXE=$(O)\test_file_util.exe
-TEST_FILE_UTIL_PDB=$(O)\test_file_util.pdb
-
-!if "$(VALID_TARGET)"=="yes"
-all: $(OUTDIR) $(TEST_FILE_UTIL_EXE)
-
-$(OUTDIR): force
- @if not exist $(OUTDIR) mkdir $(OUTDIR)
-
-clean: force
- -rmdir /S /Q $(OUTDIR)
-!else
-all clean: force
- @echo TARGET must be set to: rel, dbg, rel-unicode or dbg-unicode
-!endif
-
-$(TEST_FILE_UTIL_EXE): $(TEST_FILE_UTIL_OBJS)
- $(LD) $(LDFLAGS) /OUT:$@ \
- /PDB:$(TEST_FILE_UTIL_PDB) \
- $** $(LIBS) /SUBSYSTEM:CONSOLE /MACHINE:X86
-
-.cpp{$(OUTDIR)}.obj::
- $(CC) $(CFLAGS) -Fo$(OUTDIR)\ $<
-
-.c{$(OUTDIR)}.obj::
- $(CC) $(CFLAGS) -Fo$(OUTDIR)\ $<
-
-force: ;
-
+++ /dev/null
-/*++
-
-Copyright (c) 2003 Microsoft Corporation
-
-Abstract:
-
- Helper functions for HIDPI/Landscape support.
-
---*/
-
-#include "ms_ui_helper.h"
-
-HIDPI_ENABLE;
-
-BOOL HIDPI_StretchBitmap(
- HBITMAP* phbm,
- int cxDstImg,
- int cyDstImg,
- int cImagesX,
- int cImagesY
- )
-{
- BOOL fRet = FALSE;
- HBITMAP hbmNew;
- BITMAP bm;
- HDC hdcSrc, hdcDst, hdcScreen;
- HBITMAP hbmOldSrc, hbmOldDst;
- int cxSrcImg, cySrcImg;
- int i, j, xDest, yDest, xBmp, yBmp;
-
- if (!phbm || !*phbm || (cxDstImg == 0 && cyDstImg == 0) || (cImagesX == 0 || cImagesY == 0))
- goto donestretch;
-
- if ((sizeof(bm) != GetObject(*phbm, sizeof(bm), &bm)))
- goto donestretch;
-
- // If you hit this ASSERT, that mean your passed in image count in row and
- // the column number of images is not correct.
- // ASSERT(((bm.bmWidth % cImagesX) == 0) && ((bm.bmHeight % cImagesY) == 0));
-
- cxSrcImg = bm.bmWidth / cImagesX;
- cySrcImg = bm.bmHeight / cImagesY;
-
- if (cxSrcImg == cxDstImg && cySrcImg == cyDstImg)
- {
- fRet = TRUE;
- goto donestretch;
- }
-
- if (cxDstImg == 0)
- cxDstImg = HIDPIMulDiv(cyDstImg, cxSrcImg, cySrcImg);
- else if (cyDstImg == 0)
- cyDstImg = HIDPIMulDiv(cxDstImg, cySrcImg, cxSrcImg);
-
- hdcSrc = CreateCompatibleDC(NULL);
- hdcDst = CreateCompatibleDC(NULL);
- hdcScreen = GetDC(NULL);
- hbmOldSrc = (HBITMAP)SelectObject(hdcSrc, *phbm);
- hbmNew = CreateCompatibleBitmap(hdcScreen, cxDstImg * cImagesX, cyDstImg * cImagesY);
- hbmOldDst = (HBITMAP)SelectObject(hdcDst, hbmNew);
- ReleaseDC(NULL, hdcScreen);
-
- // BLAST!
- for (j = 0, yDest = 0, yBmp = 0; j < cImagesY; j++, yDest += cyDstImg, yBmp += cySrcImg)
- {
- for (i = 0, xDest = 0, xBmp = 0; i < cImagesX; i++, xDest += cxDstImg, xBmp += cxSrcImg)
- {
- StretchBlt(hdcDst, xDest, yDest, cxDstImg, cyDstImg,
- hdcSrc, xBmp, yBmp, cxSrcImg, cySrcImg,
- SRCCOPY);
- }
- }
-
- // Free allocated memory
- SelectObject(hdcSrc, hbmOldSrc);
- SelectObject(hdcDst, hbmOldDst);
- DeleteDC(hdcSrc);
- DeleteDC(hdcDst);
-
- // Delete the passed in bitmap
- DeleteObject(*phbm);
- *phbm = hbmNew;
-
- fRet = TRUE;
-
-donestretch:
- return fRet;
-}
-
-static BOOL HIDPI_StretchIcon_Internal(
- HICON hiconIn,
- HICON* phiconOut,
- int cxIcon,
- int cyIcon
-)
-{
- ICONINFO iconinfo;
-
- HDC hdc;
- HBITMAP hbmImage, hbmMask;
- HBITMAP hbmOld;
- BOOL fDrawMaskOK;
- BOOL fDrawImageOK;
-
- *phiconOut = NULL;
- hdc = CreateCompatibleDC(NULL);
-
- hbmMask = CreateCompatibleBitmap(hdc, cxIcon, cyIcon);
- hbmOld = (HBITMAP)SelectObject(hdc, hbmMask);
- fDrawMaskOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_MASK);
- SelectObject(hdc, hbmOld);
-
- hbmImage = CreateBitmap(cxIcon, cyIcon, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
- hbmOld = (HBITMAP)SelectObject(hdc, hbmImage);
- fDrawImageOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_IMAGE);
- SelectObject(hdc, hbmOld);
-
- if (fDrawImageOK && fDrawMaskOK)
- {
- iconinfo.fIcon = TRUE;
- iconinfo.hbmColor = hbmImage;
- iconinfo.hbmMask = hbmMask;
- *phiconOut = CreateIconIndirect(&iconinfo);
- }
-
- DeleteObject(hbmImage);
- DeleteObject(hbmMask);
-
- DeleteDC(hdc);
-
- return (fDrawImageOK && fDrawMaskOK && *phiconOut != NULL) ? TRUE : FALSE;
-}
-
-BOOL HIDPI_StretchIcon(
- HICON* phic,
- int cxIcon,
- int cyIcon
-)
-{
- HICON hiconOut;
-
- if (HIDPI_StretchIcon_Internal(*phic, &hiconOut, cxIcon, cyIcon))
- {
- DestroyIcon(*phic);
- *phic = hiconOut;
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-BOOL HIDPI_GetBitmapLogPixels(
- HINSTANCE hinst,
- LPCTSTR lpbmp,
- int* pnLogPixelsX,
- int* pnLogPixelsY
- )
-{
- BOOL fRet = FALSE;
- HRSRC hResource;
- HGLOBAL hResourceBitmap = NULL;
- BITMAPINFO* pBitmapInfo;
- int PelsPerMeterX, PelsPerMeterY;
-
- *pnLogPixelsX = 0;
- *pnLogPixelsY = 0;
-
- hResource = FindResource(hinst, lpbmp, RT_BITMAP);
- if (!hResource)
- {
- goto error;
- }
- hResourceBitmap = LoadResource(hinst, hResource);
- if (!hResourceBitmap)
- {
- goto error;
- }
- pBitmapInfo = (BITMAPINFO*)LockResource(hResourceBitmap);
- if (!pBitmapInfo)
- {
- goto error;
- }
-
- // There are at least three kind value of PslsPerMeter used for 96 DPI bitmap:
- // 0 - the bitmap just simply doesn't set this value
- // 2834 - 72 DPI
- // 3780 - 96 DPI
- // So any value of PslsPerMeter under 3780 should be treated as 96 DPI bitmap.
- PelsPerMeterX = (pBitmapInfo->bmiHeader.biXPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biXPelsPerMeter;
- PelsPerMeterY = (pBitmapInfo->bmiHeader.biYPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biYPelsPerMeter;
-
- // The formula for converting PelsPerMeter to LogPixels(DPI) is:
- // LogPixels = PelsPerMeter / 39.37
- // ( PelsPerMeter : Pixels per meter )
- // ( LogPixels : Pixels per inch )
- // Note: We need to round up.
- *pnLogPixelsX = (int)((PelsPerMeterX * 100 + 1968) / 3937);
- *pnLogPixelsY = (int)((PelsPerMeterY * 100 + 1968) / 3937);
-
- fRet = TRUE;
-
-error:
- return fRet;
-}
-
-
-HIMAGELIST HIDPI_ImageList_LoadImage(
- HINSTANCE hinst,
- LPCTSTR lpbmp,
- int cx,
- int cGrow,
- COLORREF crMask,
- UINT uType,
- UINT uFlags
- )
-{
- HBITMAP hbmImage = NULL;
- HIMAGELIST piml = NULL;
- BITMAP bm;
- int cImages, cxImage, cy;
- int BmpLogPixelsX, BmpLogPixelsY;
- UINT flags;
-
- if ((uType != IMAGE_BITMAP) || // Image type is not IMAGE_BITMAP
- (cx == 0)) // Caller doesn't care about the dimensions of the image - assumes the ones in the file
- {
- piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
- goto cleanup;
- }
-
- if (!HIDPI_GetBitmapLogPixels(hinst, lpbmp, &BmpLogPixelsX, &BmpLogPixelsY))
- {
- goto cleanup;
- }
-
- hbmImage = (HBITMAP)LoadImage(hinst, lpbmp, uType, 0, 0, uFlags);
- if (!hbmImage || (sizeof(bm) != GetObject(hbmImage, sizeof(bm), &bm)))
- {
- goto cleanup;
- }
-
- // do we need to scale this image?
- if (BmpLogPixelsX == g_HIDPI_LogPixelsX)
- {
- piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
- goto cleanup;
- }
-
- cxImage = HIDPIMulDiv(cx, BmpLogPixelsX, g_HIDPI_LogPixelsX);
-
- // Bitmap width should be multiple integral of image width.
- // If not, that means either your bitmap is wrong or passed in cx is wrong.
- // ASSERT((bm.bmWidth % cxImage) == 0);
-
- cImages = bm.bmWidth / cxImage;
-
- cy = HIDPIMulDiv(bm.bmHeight, g_HIDPI_LogPixelsY, BmpLogPixelsY);
-
- if ((g_HIDPI_LogPixelsX % BmpLogPixelsX) == 0)
- {
- HIDPI_StretchBitmap(&hbmImage, cx * cImages, cy, 1, 1);
- }
- else
- {
- // Here means the DPI is not integral multiple of standard DPI (96DPI).
- // So if we stretch entire bitmap together, we are not sure each indivisual
- // image will be stretch to right place. It is controled by StretchBlt().
- // (for example, a 16 pixel icon, the first one might be stretch to 22 pixels
- // and next one might be stretched to 20 pixels)
- // What we have to do here is stretching indivisual image separately to make sure
- // every one is stretched properly.
- HIDPI_StretchBitmap(&hbmImage, cx, cy, cImages, 1);
- }
-
- flags = 0;
- // ILC_MASK is important for supporting CLR_DEFAULT
- if (crMask != CLR_NONE)
- {
- flags |= ILC_MASK;
- }
- // ILC_COLORMASK bits are important if we ever want to Merge ImageLists
- if (bm.bmBits)
- {
- flags |= (bm.bmBitsPixel & ILC_COLORMASK);
- }
-
- // bitmap MUST be de-selected from the DC
- // create the image list of the size asked for.
- piml = ImageList_Create(cx, cy, flags, cImages, cGrow);
-
- if (piml)
- {
- int added;
-
- if (crMask == CLR_NONE)
- {
- added = ImageList_Add(piml, hbmImage, NULL);
- }
- else
- {
- added = ImageList_AddMasked(piml, hbmImage, crMask);
- }
-
- if (added < 0)
- {
- ImageList_Destroy(piml);
- piml = NULL;
- }
- }
-
-cleanup:
- DeleteObject(hbmImage);
- return piml;
-}
-
-int HIDPI_ImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon)
-{
- int iRet;
- int cxIcon, cyIcon;
- HICON hiconStretched;
-
- ImageList_GetIconSize(himl, &cxIcon, &cyIcon);
- HIDPI_StretchIcon_Internal(hicon, &hiconStretched, cxIcon, cyIcon);
- if (hiconStretched != NULL)
- {
- iRet = ImageList_ReplaceIcon(himl, i, hiconStretched);
- DestroyIcon(hiconStretched);
- }
- else
- {
- iRet = ImageList_ReplaceIcon(himl, i, hicon);
- }
-
- return iRet;
-}
-
-BOOL HIDPI_RectangleInternal(HDC hdc, int nLeft, int nTop, int nRight, int nBottom, int nThickness)
-{
- int nOff = nThickness/2;
-
- nLeft += nOff;
- nTop += nOff;
- nRight -= nOff;
- nBottom -= nOff;
-
- return Rectangle(hdc, nLeft, nTop, nRight, nBottom);
-}
-
-#define BORDERX_PEN 32
-
-BOOL HIDPI_BorderRectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom)
-{
- HPEN hpenOld;
- BOOL bRet;
-
- hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN));
- bRet = HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, GetSystemMetrics(SM_CXBORDER));
- SelectObject(hdc, hpenOld);
-
- return bRet;
-}
-
-BOOL HIDPI_Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom)
-{
- LOGPEN lpenSel;
- HPEN hpenSel;
-
- // Obtain current pen thickness
- hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN);
- GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
-
- return HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, lpenSel.lopnWidth.x);
-}
-
-
-BOOL HIDPI_PolylineInternal(HDC hdc, const POINT *lppt, int cPoints, int nStyle, int nThickness)
-{
- int i;
- int nHOff = 0, nVOff = 0;
- BOOL bRet = TRUE;
- POINT pts[2];
-
- if (! (nStyle & PS_BIAS_MASK))
- {
- // No drawing bias. Draw normally
- return Polyline(hdc, lppt, cPoints);
- }
-
- // Make sure caller didn't try to get both a left and a right bias or both a down and an up bias
- // ASSERT(!(nStyle & PS_LEFTBIAS) || !(nStyle & PS_RIGHTBIAS));
- // ASSERT(!(nStyle & PS_UPBIAS) || !(nStyle & PS_DOWNBIAS));
-
- if (nStyle & PS_LEFTBIAS)
- {
- nHOff = -((nThickness-1)/2);
- }
-
- if (nStyle & PS_RIGHTBIAS)
- {
- nHOff = nThickness/2;
- }
-
- if (nStyle & PS_UPBIAS)
- {
- nVOff = -((nThickness-1)/2);
- }
-
- if (nStyle & PS_DOWNBIAS)
- {
- nVOff = nThickness/2;
- }
-
- for (i = 1; i < cPoints; i++)
- {
- // Use the two points that specify current line segment
- memcpy(pts, &lppt[i-1], 2*sizeof(POINT));
- if (abs(lppt[i].x - lppt[i-1].x) <= abs(lppt[i].y - lppt[i-1].y))
- {
- // Shift current line segment horizontally if abs(slope) >= 1
- pts[0].x += nHOff;
- pts[1].x += nHOff;
- }
- else
- {
- // Shift current line segment vertically if abs(slope) < 1
- pts[0].y += nVOff;
- pts[1].y += nVOff;
- }
- bRet = bRet && Polyline(hdc, pts, 2);
- if (!bRet)
- {
- goto Error;
- }
- }
-
-Error:
- return bRet;
-}
-
-BOOL HIDPI_BorderPolyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle)
-{
- HPEN hpenOld;
- BOOL bRet;
-
- hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN));
- bRet = HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, GetSystemMetrics(SM_CXBORDER));
- SelectObject(hdc, hpenOld);
-
- return bRet;
-}
-
-BOOL HIDPI_Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle)
-{
- LOGPEN lpenSel;
- HPEN hpenSel;
-
- // Obtain current pen thickness
- hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN);
- GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
-
- return HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, lpenSel.lopnWidth.x);
-}
-
-//
-// Called by RelayoutDialog to advance to the next item in the dialog template.
-//
-static LPBYTE WalkDialogData(LPBYTE lpData)
-{
- LPWORD lpWord = (LPWORD)lpData;
- if (*lpWord == 0xFFFF)
- {
- return (LPBYTE)(lpWord + 2);
- }
- while (*lpWord != 0x0000)
- {
- lpWord++;
- }
- return (LPBYTE)(lpWord + 1);
-}
-
-//
-// Post-processing step for each dialog item.
-// Static controls and buttons: change text and bitmaps.
-// Listboxes and combo boxes: ensures that the selected item is visible.
-//
-static void FixupDialogItem(
- HINSTANCE hInst,
- HWND hDlg,
- LPDLGITEMTEMPLATE lpDlgItem,
- LPWORD lpClass,
- LPWORD lpData)
-{
- if (lpClass[0] == 0xFFFF)
- {
- switch (lpClass[1])
- {
- case 0x0080: // button
- case 0x0082: // static
- {
- if (lpData[0] == 0xFFFF)
- {
- if (lpDlgItem->style & SS_ICON)
- {
- HICON hOld = (HICON)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_ICON, 0);
- HICON hNew = LoadIcon(hInst, MAKEINTRESOURCE(lpData[1]));
- SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hNew);
- DestroyIcon(hOld);
- }
- else if (lpDlgItem->style & SS_BITMAP)
- {
- HBITMAP hOld = (HBITMAP)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_BITMAP, 0);
- HBITMAP hNew = LoadBitmap(hInst, MAKEINTRESOURCE(lpData[1]));
- SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hNew);
- DeleteObject(hOld);
- }
- }
- else // lpData[0] is not 0xFFFF (it's text).
- {
- SetDlgItemTextW(hDlg, lpDlgItem->id, (LPCTSTR)lpData);
- }
- }
- break;
-
- case 0x0083: // list box
- {
- INT nSel = SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_GETCURSEL, 0, 0);
- if (nSel != LB_ERR)
- {
- SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_SETCURSEL, nSel, 0);
- }
- }
- break;
-
- case 0x0085: // combo box
- {
- INT nSel = SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_GETCURSEL, 0, 0);
- if (nSel != CB_ERR)
- {
- SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_SETCURSEL, nSel, 0);
- }
- }
- break;
- }
- }
-}
-
-BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate)
-{
- HRSRC hRsrc = FindResource((HMODULE)hInst, iddTemplate, RT_DIALOG);
- INT nStatics = 0;
- HGLOBAL hGlobal;
- LPBYTE lpData;
- LPDLGTEMPLATE lpTemplate;
- HDWP hDWP;
- int i;
- LPDLGITEMTEMPLATE lpDlgItem;
- HWND hwndCtl;
- LPWORD lpClass;
- WORD cbExtra;
-
- if (hRsrc == NULL)
- {
- return FALSE;
- }
-
- hGlobal = LoadResource((HMODULE)hInst, hRsrc);
- if (hGlobal == NULL)
- {
- return FALSE;
- }
-
- lpData = (LPBYTE)LockResource(hGlobal);
- lpTemplate = (LPDLGTEMPLATE)lpData;
- hDWP = BeginDeferWindowPos(lpTemplate->cdit);
-
- //
- // For more information about the data structures that we are walking,
- // consult the DLGTEMPLATE and DLGITEMTEMPLATE documentation on MSDN.
- //
- lpData += sizeof(DLGTEMPLATE);
- lpData = WalkDialogData(lpData); // menu
- lpData = WalkDialogData(lpData); // class
- lpData = WalkDialogData(lpData); // title
-
- if (lpTemplate->style & DS_SETFONT)
- {
- lpData += sizeof(WORD); // font size.
- lpData = WalkDialogData(lpData); // font face.
- }
-
- for (i = 0; i < lpTemplate->cdit; i++)
- {
- lpData = (LPBYTE) (((INT)lpData + 3) & ~3); // force to DWORD boundary.
- lpDlgItem = (LPDLGITEMTEMPLATE)lpData;
- hwndCtl = GetDlgItem(hDlg, lpDlgItem->id);
-
- if (lpDlgItem->id == 0xFFFF)
- {
- nStatics++;
- }
-
- //
- // Move the item around.
- //
- {
- RECT r;
- r.left = lpDlgItem->x;
- r.top = lpDlgItem->y;
- r.right = lpDlgItem->x + lpDlgItem->cx;
- r.bottom = lpDlgItem->y + lpDlgItem->cy;
- MapDialogRect(hDlg, &r);
- DeferWindowPos(hDWP, hwndCtl, NULL,
- r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER);
- }
-
- lpData += sizeof(DLGITEMTEMPLATE);
- lpClass = (LPWORD)lpData;
- lpData = WalkDialogData(lpData); // class
-
- //
- // Do some special handling for each dialog item (changing text,
- // bitmaps, ensuring visible, etc.
- //
- FixupDialogItem(hInst, hDlg, lpDlgItem, lpClass, (LPWORD)lpData);
-
- lpData = WalkDialogData(lpData); // title
- cbExtra = *((LPWORD)lpData); // extra class data.
- lpData += (cbExtra ? cbExtra : sizeof(WORD));
- }
-
- EndDeferWindowPos(hDWP);
- return nStatics < 2 ? TRUE : FALSE;
-}
+++ /dev/null
-/*++
-
-Copyright (c) 2003 Microsoft Corporation
-
-Module Name:
-
- uihelper.h
-
-Abstract:
-
- Include file for HIDPI / orientation / font change helper functions.
-
---*/
-
-#ifndef __UIHELPER_H__
-#define __UIHELPER_H__
-
-#include <windows.h>
-#include <commctrl.h>
-#include "ms_ui_shguim.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// HIDPI functions and constants.
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef ILC_COLORMASK
-#define ILC_COLORMASK 0x00FE
-#endif
-
-//
-// The two macros HIDPISIGN and HIDPIABS are there to ensure correct rounding
-// for negative numbers passed into HIDPIMulDiv as x (we want -1.5 to round
-// to -1, 2.5 to round to 2, etc). So we use the absolute value of x, and then
-// multiply the result by the sign of x. Y and z should never be negative, as
-// y is the dpi of the device (presumably 192 or 96), and z is always 96, as
-// that is our original dpi we developed on.
-//
-
-#define HIDPISIGN(x) (((x)<0)?-1:1)
-#define HIDPIABS(x) (((x)<0)?-(x):x)
-#define HIDPIMulDiv(x,y,z) ((((HIDPIABS(x)*(y))+((z)>>1))/(z))*HIDPISIGN(x))
-
-//
-// Cached values of GetDeviceCaps(LOGPIXELSX/Y) for the screen DC.
-//
-EXTERN_C int g_HIDPI_LogPixelsX;
-EXTERN_C int g_HIDPI_LogPixelsY;
-
-//
-// You need to define these somewhere in your .c files only if you make use of
-// the scaling macros. (Defined in UIHelper.cpp).
-//
-#define HIDPI_ENABLE \
- int g_HIDPI_LogPixelsX; \
- int g_HIDPI_LogPixelsY;
-
-//
-// Scaling macros.
-//
-#define SCALEX(argX) (HIDPIMulDiv(argX,g_HIDPI_LogPixelsX,96))
-#define SCALEY(argY) (HIDPIMulDiv(argY,g_HIDPI_LogPixelsY,96))
-
-#define UNSCALEX(argX) (HIDPIMulDiv(argX,96,g_HIDPI_LogPixelsX))
-#define UNSCALEY(argY) (HIDPIMulDiv(argY,96,g_HIDPI_LogPixelsY))
-
-#define SCALERECT(rc) { rc.left = SCALEX(rc.left); rc.right = SCALEX(rc.right); rc.top = SCALEY(rc.top); rc.bottom = SCALEY(rc.bottom);}
-#define SCALEPT(pt) { pt.x = SCALEX(pt.x); pt.y = SCALEY(pt.y);}
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_InitScaling
-//
-// PURPOSE: Initializes g_HIDPI_LogPixelsX and g_HIDPI_LogPixelsY. This
-// should be called once at the beginning of any HIDPI-aware application.
-//
-__inline void HIDPI_InitScaling()
-{
- HDC screen;
-
- if( g_HIDPI_LogPixelsX )
- return;
-
- screen = GetDC(NULL);
- g_HIDPI_LogPixelsX = GetDeviceCaps(screen, LOGPIXELSX);
- g_HIDPI_LogPixelsY = GetDeviceCaps(screen, LOGPIXELSY);
- ReleaseDC(NULL, screen);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_StretchBitmap
-//
-// PURPOSE: Stretches a bitmap containing a grid of images. There are
-// cImagesX images per row and cImagesY rows per bitmap. Each image is
-// scaled individually, so that there are no artifacts with non-integral
-// scaling factors. If the bitmap contains only one image, set cImagesX
-// and cImagesY to 1.
-//
-// ON ENTRY:
-// HBITMAP* phbm: a pointer to the bitmap to be scaled.
-// INT cxDstImg: the width of each image after scaling.
-// INT cyDstImg: the height of each image after scaling.
-// INT cImagesX: the number of images per row. This value should
-// evenly divide the width of the bitmap.
-// INT cImagesY: the number of rows in the bitmap. This value should
-// evenly divide the height of the bitmap.
-//
-// ON EXIT:
-// Returns TRUE on success, FALSE on failure.
-//
-// If any scaling has occured, the bitmap pointed to by phbm is deleted
-// and is replaced by a new bitmap handle.
-//
-BOOL HIDPI_StretchBitmap(
- HBITMAP* phbm,
- int cxDstImg,
- int cyDstImg,
- int cImagesX,
- int cImagesY
- );
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_GetBitmapLogPixels
-//
-// PURPOSE: retrieves the DPI fields of the specified bitmap.
-//
-// ON ENTRY:
-// HINSTANCE hinst: the HINSTANCE of the bitmap resource.
-// LPCTSTR lpbmp: the ID of the bitmap resource. The MAKEINTRESOURCE
-// macro can be used for integer IDs.
-// INT* pnLogPixelsX: the returned value for the horizontal DPI field of
-// the bitmap. This value is never less than 96.
-// INT* pnLogPixelsY: the returned value for the vertical DPI field of
-// the bitmap. This value is never less than 96.
-//
-// ON EXIT:
-// Returns TRUE on success, FALSE on failure.
-//
-BOOL HIDPI_GetBitmapLogPixels(
- HINSTANCE hinst,
- LPCTSTR lpbmp,
- int* pnLogPixelsX,
- int* pnLogPixelsY
- );
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_StretchIcon
-//
-// PURPOSE: stretches an icon to the specified size on 4.21 devices and later.
-// On 4.20 and previous revisions of the OS, this is a no-op.
-//
-// ON ENTRY:
-// HICON* phic: the icon to stretch.
-// INT cxIcon: the desired width of the icon.
-// INT cyIcon: the desired height of the icon.
-//
-// ON EXIT:
-// Returns TRUE on success, FALSE on failure.
-//
-// If any stretching occurred, the icon pointed to by phic is deleted and
-// is replaced by a new icon handle.
-//
-BOOL HIDPI_StretchIcon(
- HICON* phic,
- int cxIcon,
- int cyIcon
- );
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_ImageList_LoadImage
-//
-// PURPOSE: This function operates identically to ImageList_LoadImage, except
-// that it first checks the DPI fields of the bitmap (using
-// HIDPI_GetBitmapLogPixels); compares it to the DPI of the screen
-// (using g_HIDPI_LogPixelsX and g_HIDPI_LogPixelsY), and performs scaling
-// (using HIDPI_StretchBitmap) if the values are different.
-//
-// ON ENTRY:
-// See the MSDN documentation for ImageList_LoadImage.
-//
-// ON EXIT:
-// See the MSDN documentation for ImageList_LoadImage.
-//
-HIMAGELIST HIDPI_ImageList_LoadImage(
- HINSTANCE hinst,
- LPCTSTR lpbmp,
- int cx,
- int cGrow,
- COLORREF crMask,
- UINT uType,
- UINT uFlags
- );
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_ImageList_ReplaceIcon
-//
-// PURPOSE: Replaces an icon in an ImageList, scaling it from its original size
-// to the size of the images in the ImageList.
-//
-// ON ENTRY:
-// See the MSDN documentation for ImageList_ReplaceIcon.
-//
-// ON EXIT:
-// See the MSDN documentation for ImageList_ReplaceIcon.
-//
-int HIDPI_ImageList_ReplaceIcon(
- HIMAGELIST himl,
- int i,
- HICON hicon
- );
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_ImageList_AddIcon
-//
-// PURPOSE: Adds an icon to an ImageList, scaling it from its original size
-// to the size of the images in the ImageList.
-//
-// ON ENTRY:
-// See the MSDN documentation for ImageList_AddIcon.
-//
-// ON EXIT:
-// See the MSDN documentation for ImageList_AddIcon.
-//
-#define HIDPI_ImageList_AddIcon(himl, hicon) HIDPI_ImageList_ReplaceIcon(himl, -1, hicon)
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_Rectangle
-//
-// PURPOSE: Draws a rectangle using the currently selected pen. Drawing occurs
-// completely within the drawing rectangle (the rectangle has an "inside
-// frame" drawing style).
-//
-// ON ENTRY:
-// HDC hdc: the display context of the drawing surface.
-// INT nLeft: left bound of rectangle
-// INT nTop: top bound of rectangle
-// INT nRight: right bound of rectangle plus one.
-// INT nBottom: bottom bound of rectangle plus one.
-//
-// ON EXIT:
-// Returns TRUE on success, FALSE on failure.
-//
-BOOL HIDPI_Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom);
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_BorderRectangle
-//
-// PURPOSE: Draws a rectangle with the system border pen. Drawing occurs
-// completely within the drawing rectangle (the rectangle has an "inside
-// frame" drawing style).
-//
-// ON ENTRY:
-// HDC hdc: the display context of the drawing surface.
-// INT nLeft: left bound of rectangle
-// INT nTop: top bound of rectangle
-// INT nRight: right bound of rectangle plus one.
-// INT nBottom: bottom bound of rectangle plus one.
-//
-// ON EXIT:
-// Returns TRUE on success, FALSE on failure.
-//
-BOOL HIDPI_BorderRectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom);
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_Polyline
-//
-// PURPOSE: Draws a polyline using the currently selected pen. In addition,
-// this function provides control over how the line will be drawn.
-//
-// ON ENTRY:
-// HDC hdc: the display context of the drawing surface.
-// const POINT* lppt: array of POINTS that specify line to draw.
-// INT cPoints: number of points in array.
-// INT nStyle: the style the pen should be drawn in. This may be an
-// existing pen style, such as PS_SOLID, or one of the following styles:
-//
-// PS_LEFTBIAS PS_UPBIAS PS_UPLEFT
-// PS_RIGHTBIAS PS_DOWNBIAS PS_DOWNRIGHT
-//
-// These styles indicate how the pen should "hang" from each line
-// segment. By default, the pen is centered along the line, but with
-// these line styles the developer can draw lines above, below, to the
-// left or to the right of the line segment.
-//
-// ON EXIT:
-// Returns TRUE on success, FALSE on failure.
-//
-
-#define PS_RIGHTBIAS 0x10
-#define PS_LEFTBIAS 0x20
-#define PS_DOWNBIAS 0x40
-#define PS_UPBIAS 0x80
-#define PS_DOWNRIGHT (PS_DOWNBIAS | PS_RIGHTBIAS)
-#define PS_UPLEFT (PS_UPBIAS | PS_LEFTBIAS)
-#define PS_BIAS_MASK (PS_RIGHTBIAS | PS_LEFTBIAS | PS_DOWNBIAS | PS_UPBIAS)
-
-BOOL HIDPI_Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle);
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: HIDPI_BorderPolyline
-//
-// PURPOSE: Draws a polyline, but with the system border pen. In addition,
-// this function provides control over how the line will be drawn.
-//
-// ON ENTRY:
-// HDC hdc: the display context of the drawing surface.
-// const POINT* lppt: array of POINTS that specify line to draw.
-// INT cPoints: number of points in array.
-// INT nStyle: the style the pen should be drawn in. See HIDPI_Polyline
-// for more details.
-//
-// ON EXIT:
-// Returns TRUE on success, FALSE on failure.
-//
-BOOL HIDPI_BorderPolyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle);
-
-////////////////////////////////////////////////////////////////////////////////
-// Orientation functions.
-////////////////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: RelayoutDialog
-//
-// PURPOSE: Re-lays out a dialog based on a dialog template. This function
-// iterates through all the child window controls and does a SetWindowPos
-// for each. It also does a SetWindowText for each static text control
-// and updates the selected bitmap or icon in a static image control.
-// This assumes that the current dialog and the new template have all the
-// same controls, with the same IDCs.
-//
-// ON ENTRY:
-// HINSTANCE hInst: the hInstance of the current module.
-// HWND hDlg: the dialog to layout.
-// LPCWSTR iddTemplate: the new template for the dialog (can use
-// the MAKEINTRESOURCE macro).
-//
-// ON EXIT: TRUE if success; FALSE if failure (either the iddTemplate is
-// invalid, or there are two or more IDC_STATICs in the template).
-//
-BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __UIHELPER_H__
+++ /dev/null
-/*++
-
-Copyright (c) 2003 Microsoft Corporation
-
-Abstract:
-
- Include file for SHGetUIMetric.
-
---*/
-
-#ifndef __SHGUIM_H__
-#define __SHGUIM_H__
-
-#include <windows.h>
-
-//
-// Call RegisterWindowMessage on this string if you are interested in knowing
-// when the UI metrics have changed. wParam will be 0, lParam will be one of the
-// SHUIMETRICTYPE values to indicate what value has changed. Call SHGetUIMetrics
-// to find out the new value.
-//
-#define SH_UIMETRIC_CHANGE TEXT("SH_UIMETRIC_CHANGE")
-
-#if _MSC_VER >= 1400
-#include <aygshell.h>
-#else
-
-//
-// Enumeration of metrics you can ask for. Note that you will only receive a
-// notification for SHUIM_FONTSIZE_POINT when any these three values changes.
-//
-typedef enum tagSHUIMETRIC
-{
- SHUIM_INVALID = 0, // Illegal
- SHUIM_FONTSIZE_POINT, // Application font size (hundredths of a point) -- buffer is pointer to DWORD
- SHUIM_FONTSIZE_PIXEL, // Application font size (in pixels) -- buffer is pointer to DWORD
- SHUIM_FONTSIZE_PERCENTAGE, // Application font size as percentage of normal -- buffer is pointer to DWORD
-} SHUIMETRIC;
-
-typedef HRESULT (*PSHGETUIMETRICS)(SHUIMETRIC, PVOID, DWORD, DWORD*);
-
-//////////////////////////////////////////////////////////////////////////////
-// FUNCTION: SHGetUIMetrics
-//
-// PURPOSE: retrieves the shell's UI metrics. Although this function does not
-// exist in the Pocket PC 2003 SDK, it exists AYGSHELL.DLL in newer
-// versions of the Pocket PC. This function simply LoadLibrary's AYGSHELL
-// and calls the function if it exists.
-//
-// ON ENTRY:
-// SHUIMETRIC shuim: the metric to retrieve.
-// PVOID pvBuffer: the retrieved data for the metric.
-// DWORD cbBufferSize: the size of pvBuffer (should be sizeof(DWORD)).
-// DWORD* pcbRequired: retrieves the minimum size of the buffer necessary
-// to get the specified system UI metric. This can be NULL.
-//
-
-__inline HRESULT SHGetUIMetrics(SHUIMETRIC shuim, PVOID pvBuffer, DWORD cbBufferSize, DWORD *pcbRequired)
-{
- PSHGETUIMETRICS pSHGetUIMetrics = (PSHGETUIMETRICS)GetProcAddress(LoadLibrary(_T("AYGSHELL")), _T("SHGetUIMetrics"));
- if (pSHGetUIMetrics)
- {
- return pSHGetUIMetrics(shuim, pvBuffer, cbBufferSize, pcbRequired);
- }
- else if (pvBuffer != NULL && cbBufferSize >= sizeof(DWORD))
- {
- //
- // Not supported on this version of Pocket PC, so come up with a reasonable default.
- //
- LOGFONT lf;
- HFONT hFont = (HFONT)GetStockObject(SYSTEM_FONT);
- GetObject(hFont, sizeof(lf), &lf);
- switch (shuim)
- {
- case SHUIM_FONTSIZE_POINT:
- {
- HDC hDC = GetDC(NULL);
- int nDPI = GetDeviceCaps(hDC, LOGPIXELSY);
- ReleaseDC(NULL, hDC);
- *(DWORD*)pvBuffer = (-lf.lfHeight * 7200) / nDPI;
- break;
- }
- case SHUIM_FONTSIZE_PIXEL: *(DWORD*)pvBuffer = -lf.lfHeight; break;
- case SHUIM_FONTSIZE_PERCENTAGE: *(DWORD*)pvBuffer = 100; break;
- }
- }
- else if (pcbRequired)
- {
- *pcbRequired = sizeof(DWORD);
- }
- return S_OK;
-}
-
-#endif
-
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "base_util.h"
-#include "tstr_util.h"
-#include "netstr.h"
-
-/* Implements djb idea of net strings */
-/* Return the number of digits needed to represents a given number in base 10
- string representation.
-*/
-size_t digits_for_number(int num)
-{
- size_t digits = 1;
- /* negative numbers need '-' in front of them */
- if (num < 0) {
- ++digits;
- num = -num;
- }
-
- while (num >= 10)
- {
- ++digits;
- num = num / 10;
- }
- return digits;
-}
-
-/* Netstring format is a safe, easy and mostly human readable format for
- serializing strings (well, any binary data). Netstring format is:
- - a byte length of the data as a string
- - ':' (single character)
- - data
- - ',' (single character)
- e.g. "foo" is encoded as "3:foo,"
- I learned about netstring format from djb (http://cr.yp.to/proto/netstrings.txt)
-*/
-size_t netstr_tstrn_serialized_len_cb(size_t str_len_cch)
-{
- size_t total_len_cch;
-
- /* 2 is for ':" and ',' */
- total_len_cch = str_len_cch + digits_for_number((int)str_len_cch) + 2;
- return total_len_cch * sizeof(TCHAR);
-}
-
-/* Return number of bytes needed to serialize string 'str' in netstring format. */
-size_t netstr_tstr_serialized_len_cb(const TCHAR *str)
-{
- size_t str_len_cch;
-
- if (!str) return 0;
- str_len_cch = tstr_len(str);
- return netstr_tstrn_serialized_len_cb(str_len_cch);
-}
-
-/* Return number of bytes needed to serialize integer 'num' in netstring format. */
-size_t netstr_int_serialized_len_cb(int num)
-{
- size_t str_len_cch;
- size_t total_len_cch;
-
- str_len_cch = digits_for_number(num);
- total_len_cch = str_len_cch + digits_for_number((int)str_len_cch) + 2;
- return total_len_cch * sizeof(TCHAR);
-}
-
-int netstr_tstr_serialize(const TCHAR *str, TCHAR **buf_ptr, size_t *buf_len_cb_ptr)
-{
- char * buf;
- size_t buf_len_cb;
- size_t len_needed_cb;
- TCHAR * num_str;
- size_t str_len_cch;
- size_t len_cb;
- size_t total_len_cb = 0;
-
- assert(buf_len_cb_ptr);
- if (!buf_len_cb_ptr)
- return FALSE;
-
- if (!buf_ptr)
- {
- *buf_len_cb_ptr += netstr_tstr_serialized_len_cb(str);
- return TRUE;
- }
-
- buf = (char*)*buf_ptr;
- assert(buf);
- if (!buf)
- return FALSE;
-
- buf_len_cb = *buf_len_cb_ptr;
- assert(buf_len_cb > 0);
- if (buf_len_cb <= 0)
- return FALSE;
-
- len_needed_cb = netstr_tstr_serialized_len_cb(str);
- if (len_needed_cb > buf_len_cb)
- return FALSE;
-
- str_len_cch = tstr_len(str);
- num_str = tstr_printf(_T("%d:"), str_len_cch);
- if (!num_str)
- return FALSE;
-
- len_cb = tstr_len(num_str)*sizeof(TCHAR);
- memcpy(buf, num_str, len_cb);
- buf += len_cb;
- total_len_cb += len_cb;
- assert(total_len_cb <= len_needed_cb);
- len_cb = tstr_len(str)*sizeof(TCHAR);
- memcpy(buf, str, len_cb);
- buf += len_cb;
- total_len_cb += len_cb;
- assert(total_len_cb <= len_needed_cb);
- len_cb = sizeof(TCHAR);
- memcpy(buf, _T(","), len_cb);
- buf += len_cb;
- total_len_cb += len_cb;
- assert(total_len_cb == len_needed_cb);
-
- *buf_len_cb_ptr -= total_len_cb;
- *buf_ptr = (TCHAR*)buf;
- free((void*)num_str);
- return TRUE;
-}
-
-int netstr_int_serialize(int num, TCHAR **buf_ptr, size_t *buf_len_cb_ptr)
-{
- TCHAR * num_str;
- int f_ok;
-
- assert(buf_len_cb_ptr);
- if (!buf_len_cb_ptr)
- return FALSE;
-
- if (!buf_ptr)
- {
- *buf_len_cb_ptr += netstr_int_serialized_len_cb(num);
- return TRUE;
- }
-
- num_str = tstr_printf(_T("%d"), num);
- if (!num_str)
- return FALSE;
-
- f_ok = netstr_tstr_serialize(num_str, buf_ptr, buf_len_cb_ptr);
- free((void*)num_str);
- return f_ok;
-}
-
-/* Parse a netstring number i.e. a list of digits until ':', skipping ':'.
- Returns FALSE if there's an error parsing (string doesn't follow the format) */
-static int netstr_get_str_len(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *num_out)
-{
- int num = 0;
- const TCHAR * tmp;
- size_t str_len_cb;
- TCHAR c;
- int digit = 0;
-
- assert(str_ptr);
- if (!str_ptr)
- return FALSE;
- assert(str_len_cb_ptr);
- if (!str_len_cb_ptr)
- return FALSE;
- assert(num_out);
- if (!num_out)
- return FALSE;
-
- tmp = *str_ptr;
- assert(tmp);
- if (!tmp)
- return FALSE;
-
- str_len_cb = *str_len_cb_ptr;
- assert(str_len_cb > 0);
- if (str_len_cb <= 0)
- return FALSE;
-
- for (;;) {
- str_len_cb -= sizeof(TCHAR);
- if (str_len_cb < 0)
- return FALSE;
- c = *tmp++;
- if (_T(':') == c)
- break;
- if ( (c >= _T('0')) && (c <= _T('9')) )
- digit = (int)c - _T('0');
- else
- return FALSE;
- num = (num * 10) + digit;
- }
- if (str_len_cb == *str_len_cb_ptr)
- return FALSE;
-
- *str_ptr = tmp;
- *str_len_cb_ptr = str_len_cb;
- *num_out = num;
- return TRUE;
-}
-
-int netstr_valid_separator(TCHAR c)
-{
- if (c == _T(','))
- return TRUE;
- return FALSE;
-}
-
-int netstr_parse_str(const TCHAR **str_ptr, size_t *str_len_cb_ptr, const TCHAR **str_out, size_t *str_len_cch_out)
-{
- int f_ok;
- size_t str_len_cch;
- size_t str_len_cb;
- const TCHAR * str;
- const TCHAR * str_copy;
- int num;
-
- f_ok = netstr_get_str_len(str_ptr, str_len_cb_ptr, &num);
- if (!f_ok)
- return FALSE;
- assert(num >= 0);
- str_len_cch = (size_t)num;
- str_len_cb = (str_len_cch+1)*sizeof(TCHAR);
- if (str_len_cb > *str_len_cb_ptr)
- return FALSE;
-
- str = *str_ptr;
- if (!netstr_valid_separator(str[str_len_cch]))
- return FALSE;
- str_copy = (const TCHAR*)tstr_dupn(str, str_len_cch);
- if (!str_copy)
- return FALSE;
- *str_out = str_copy;
- *str_len_cch_out = str_len_cch;
- *str_ptr = str + str_len_cch + 1;
- *str_len_cb_ptr -= str_len_cb ;
- return TRUE;
-}
-
-int netstr_parse_int(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *int_out)
-{
- const TCHAR * str = NULL;
- const TCHAR * tmp;
- TCHAR c;
- size_t str_len_cch;
- int f_ok;
- int num = 0;
- int digit = 0;
-
- f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &str, &str_len_cch);
- if (!f_ok)
- return FALSE;
-
- tmp = str;
- while (*tmp) {
- c = *tmp++;
- if ( (c >= _T('0')) && (c <= _T('9')) )
- digit = (int)c - _T('0');
- else
- goto Error;
- num = (num * 10) + digit;
- }
- *int_out = num;
- free((void*)str);
- return TRUE;
-Error:
- free((void*)str);
- return FALSE;
-}
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef NETSTR_H__
-#define NETSTR_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#define NETSTR_SEP_TC _T(':')
-#define NETSTR_END_TC _T(',')
-
-size_t digits_for_number(int num);
-
-size_t netstr_int_serialized_len_cb(int num);
-size_t netstr_tstr_serialized_len_cb(const TCHAR *str);
-size_t netstr_tstrn_serialized_len_cb(size_t str_len_cch);
-int netstr_tstr_serialize(const TCHAR *str, TCHAR **buf_ptr, size_t *buf_len_cb_ptr);
-int netstr_int_serialize(int num, TCHAR **buf_ptr, size_t *buf_len_cb_ptr);
-int netstr_parse_str(const TCHAR **str_ptr, size_t *str_len_cb_ptr, const TCHAR **str_out, size_t *str_len_cch_out);
-int netstr_parse_int(const TCHAR **str_ptr, size_t *str_len_cb_ptr, int *int_out);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "netstr.h"
-
-void netstr_ut(void)
-{
- assert(1 == digits_for_number(0));
- assert(1 == digits_for_number(9));
- assert(2 == digits_for_number(10));
- assert(2 == digits_for_number(19));
- assert(2 == digits_for_number(25));
- assert(3 == digits_for_number(125));
- assert(4 == digits_for_number(3892));
- assert(5 == digits_for_number(38392));
- assert(6 == digits_for_number(889931));
- assert(7 == digits_for_number(7812345));
-
- assert(1 == digits_for_number(-0));
- assert(2 == digits_for_number(-9));
- assert(3 == digits_for_number(-10));
- assert(4 == digits_for_number(-125));
- assert(5 == digits_for_number(-3892));
- assert(6 == digits_for_number(-38392));
- assert(7 == digits_for_number(-889931));
- assert(8 == digits_for_number(-7812345));
-}
+++ /dev/null
-/*
-Copyright (C) 2006 Yangli Hector Yee
-
-This program is free software; you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program;
-if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Code from http://pdiff.svn.sourceforge.net
-*/
-
-#include "pdiff.h"
-#include <math.h>
-#include <stdio.h>
-
-#ifndef M_PI
-#define M_PI 3.14159265f
-#endif
-
-CompareArgs::CompareArgs()
-{
- ImgA = NULL;
- ImgB = NULL;
- ImgDiff = NULL;
- FieldOfView = 45.0f;
- Gamma = 2.2f;
- Luminance = 100.0f;
-}
-
-CompareArgs::~CompareArgs()
-{
- if (ImgA) delete ImgA;
- if (ImgB) delete ImgB;
- if (ImgDiff) delete ImgDiff;
-}
-
-#define MAX_PYR_LEVELS 8
-
-class LPyramid
-{
-public:
- LPyramid(float *image, int width, int height);
- virtual ~LPyramid();
- float Get_Value(int x, int y, int level);
-protected:
- float *Copy(float *img);
- void Convolve(float *a, float *b);
-
- // Succesively blurred versions of the original image
- float *Levels[MAX_PYR_LEVELS];
-
- int Width;
- int Height;
-};
-
-LPyramid::LPyramid(float *image, int width, int height) :
- Width(width),
- Height(height)
-{
- // Make the Laplacian pyramid by successively
- // copying the earlier levels and blurring them
- for (int i=0; i<MAX_PYR_LEVELS; i++) {
- if (i == 0) {
- Levels[i] = Copy(image);
- } else {
- Levels[i] = new float[Width * Height];
- Convolve(Levels[i], Levels[i - 1]);
- }
- }
-}
-
-LPyramid::~LPyramid()
-{
- for (int i=0; i<MAX_PYR_LEVELS; i++) {
- if (Levels[i]) delete Levels[i];
- }
-}
-
-float *LPyramid::Copy(float *img)
-{
- int max = Width * Height;
- float *out = new float[max];
- for (int i = 0; i < max; i++) out[i] = img[i];
-
- return out;
-}
-
-void LPyramid::Convolve(float *a, float *b)
-// convolves image b with the filter kernel and stores it in a
-{
- int y,x,i,j,nx,ny;
- const float Kernel[] = {0.05f, 0.25f, 0.4f, 0.25f, 0.05f};
-
- for (y=0; y<Height; y++) {
- for (x=0; x<Width; x++) {
- int index = y * Width + x;
- a[index] = 0.0f;
- for (i=-2; i<=2; i++) {
- for (j=-2; j<=2; j++) {
- nx=x+i;
- ny=y+j;
- if (nx<0) nx=-nx;
- if (ny<0) ny=-ny;
- if (nx>=Width) nx=2*(Width-1)-nx;
- if (ny>=Height) ny=2*(Height-1)-ny;
- a[index] += Kernel[i+2] * Kernel[j+2] * b[ny * Width + nx];
- }
- }
- }
- }
-}
-
-float LPyramid::Get_Value(int x, int y, int level)
-{
- int index = x + y * Width;
- int l = level;
- if (l > MAX_PYR_LEVELS) l = MAX_PYR_LEVELS;
- return Levels[level][index];
-}
-
-/*
-* Given the adaptation luminance, this function returns the
-* threshold of visibility in cd per m^2
-* TVI means Threshold vs Intensity function
-* This version comes from Ward Larson Siggraph 1997
-*/
-
-float tvi(float adaptation_luminance)
-{
- // returns the threshold luminance given the adaptation luminance
- // units are candelas per meter squared
-
- float log_a, r, result;
- log_a = log10f(adaptation_luminance);
-
- if (log_a < -3.94f) {
- r = -2.86f;
- } else if (log_a < -1.44f) {
- r = powf(0.405f * log_a + 1.6f , 2.18f) - 2.86f;
- } else if (log_a < -0.0184f) {
- r = log_a - 0.395f;
- } else if (log_a < 1.9f) {
- r = powf(0.249f * log_a + 0.65f, 2.7f) - 0.72f;
- } else {
- r = log_a - 1.255f;
- }
-
- result = powf(10.0f , r);
-
- return result;
-
-}
-
-// computes the contrast sensitivity function (Barten SPIE 1989)
-// given the cycles per degree (cpd) and luminance (lum)
-float csf(float cpd, float lum)
-{
- float a, b, result;
-
- a = 440.0f * powf((1.0f + 0.7f / lum), -0.2f);
- b = 0.3f * powf((1.0f + 100.0f / lum), 0.15f);
-
- result = a * cpd * expf(-b * cpd) * sqrtf(1.0f + 0.06f * expf(b * cpd));
-
- return result;
-}
-
-/*
-* Visual Masking Function
-* from Daly 1993
-*/
-float mask(float contrast)
-{
- float a, b, result;
- a = powf(392.498f * contrast, 0.7f);
- b = powf(0.0153f * a, 4.0f);
- result = powf(1.0f + b, 0.25f);
-
- return result;
-}
-
-// convert Adobe RGB (1998) with reference white D65 to XYZ
-void AdobeRGBToXYZ(float r, float g, float b, float &x, float &y, float &z)
-{
- // matrix is from http://www.brucelindbloom.com/
- x = r * 0.576700f + g * 0.185556f + b * 0.188212f;
- y = r * 0.297361f + g * 0.627355f + b * 0.0752847f;
- z = r * 0.0270328f + g * 0.0706879f + b * 0.991248f;
-}
-
-void XYZToLAB(float x, float y, float z, float &L, float &A, float &B)
-{
- static float xw = -1;
- static float yw;
- static float zw;
- // reference white
- if (xw < 0) {
- AdobeRGBToXYZ(1, 1, 1, xw, yw, zw);
- }
- const float epsilon = 216.0f / 24389.0f;
- const float kappa = 24389.0f / 27.0f;
- float f[3];
- float r[3];
- r[0] = x / xw;
- r[1] = y / yw;
- r[2] = z / zw;
- for (int i = 0; i < 3; i++) {
- if (r[i] > epsilon) {
- f[i] = powf(r[i], 1.0f / 3.0f);
- } else {
- f[i] = (kappa * r[i] + 16.0f) / 116.0f;
- }
- }
- L = 116.0f * f[1] - 16.0f;
- A = 500.0f * (f[0] - f[1]);
- B = 200.0f * (f[1] - f[2]);
-}
-
-unsigned long Yee_Compare(CompareArgs &args)
-{
- if ((args.ImgA->Get_Width() != args.ImgB->Get_Width()) ||
- (args.ImgA->Get_Height() != args.ImgB->Get_Height())) {
- return DIFFERENT_SIZES;
- }
-
- unsigned int i, dim;
- dim = args.ImgA->Get_Width() * args.ImgA->Get_Height();
- bool identical = true;
- for (i = 0; i < dim; i++) {
- if (args.ImgA->Get(i) != args.ImgB->Get(i)) {
- identical = false;
- break;
- }
- }
- if (identical) {
- return IDENTICAL;
- }
-
- // assuming colorspaces are in Adobe RGB (1998) convert to XYZ
- float *aX = new float[dim];
- float *aY = new float[dim];
- float *aZ = new float[dim];
- float *bX = new float[dim];
- float *bY = new float[dim];
- float *bZ = new float[dim];
- float *aLum = new float[dim];
- float *bLum = new float[dim];
-
- float *aA = new float[dim];
- float *bA = new float[dim];
- float *aB = new float[dim];
- float *bB = new float[dim];
-
- unsigned int x, y, w, h;
- w = args.ImgA->Get_Width();
- h = args.ImgA->Get_Height();
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- float r, g, b, l;
- i = x + y * w;
- r = powf(args.ImgA->Get_Red(i) / 255.0f, args.Gamma);
- g = powf(args.ImgA->Get_Green(i) / 255.0f, args.Gamma);
- b = powf(args.ImgA->Get_Blue(i) / 255.0f, args.Gamma);
- AdobeRGBToXYZ(r,g,b,aX[i],aY[i],aZ[i]);
- XYZToLAB(aX[i], aY[i], aZ[i], l, aA[i], aB[i]);
- r = powf(args.ImgB->Get_Red(i) / 255.0f, args.Gamma);
- g = powf(args.ImgB->Get_Green(i) / 255.0f, args.Gamma);
- b = powf(args.ImgB->Get_Blue(i) / 255.0f, args.Gamma);
- AdobeRGBToXYZ(r,g,b,bX[i],bY[i],bZ[i]);
- XYZToLAB(bX[i], bY[i], bZ[i], l, bA[i], bB[i]);
- aLum[i] = aY[i] * args.Luminance;
- bLum[i] = bY[i] * args.Luminance;
- }
- }
-
- LPyramid *la = new LPyramid(aLum, w, h);
- LPyramid *lb = new LPyramid(bLum, w, h);
-
- float num_one_degree_pixels = (float) (2 * tan( args.FieldOfView * 0.5 * M_PI / 180) * 180 / M_PI);
- float pixels_per_degree = w / num_one_degree_pixels;
-
- float num_pixels = 1;
- unsigned int adaptation_level = 0;
- for (i = 0; i < MAX_PYR_LEVELS; i++) {
- adaptation_level = i;
- if (num_pixels > num_one_degree_pixels) break;
- num_pixels *= 2;
- }
-
- float cpd[MAX_PYR_LEVELS];
- cpd[0] = 0.5f * pixels_per_degree;
- for (i = 1; i < MAX_PYR_LEVELS; i++) cpd[i] = 0.5f * cpd[i - 1];
- float csf_max = csf(3.248f, 100.0f);
-
- float F_freq[MAX_PYR_LEVELS - 2];
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) F_freq[i] = csf_max / csf( cpd[i], 100.0f);
-
- unsigned int pixels_failed = 0;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- int index = x + y * w;
- float contrast[MAX_PYR_LEVELS - 2];
- float sum_contrast = 0;
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
- float n1 = fabsf(la->Get_Value(x,y,i) - la->Get_Value(x,y,i + 1));
- float n2 = fabsf(lb->Get_Value(x,y,i) - lb->Get_Value(x,y,i + 1));
- float numerator = (n1 > n2) ? n1 : n2;
- float d1 = fabsf(la->Get_Value(x,y,i+2));
- float d2 = fabsf(lb->Get_Value(x,y,i+2));
- float denominator = (d1 > d2) ? d1 : d2;
- if (denominator < 1e-5f) denominator = 1e-5f;
- contrast[i] = numerator / denominator;
- sum_contrast += contrast[i];
- }
- if (sum_contrast < 1e-5) sum_contrast = 1e-5f;
- float F_mask[MAX_PYR_LEVELS - 2];
- float adapt = la->Get_Value(x,y,adaptation_level) + lb->Get_Value(x,y,adaptation_level);
- adapt *= 0.5f;
- if (adapt < 1e-5) adapt = 1e-5f;
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
- F_mask[i] = mask(contrast[i] * csf(cpd[i], adapt));
- }
- float factor = 0;
- for (i = 0; i < MAX_PYR_LEVELS - 2; i++) {
- factor += contrast[i] * F_freq[i] * F_mask[i] / sum_contrast;
- }
- if (factor < 1) factor = 1;
- if (factor > 10) factor = 10;
- float delta = fabsf(la->Get_Value(x,y,0) - lb->Get_Value(x,y,0));
- bool pass = true;
- // pure luminance test
- if (delta > factor * tvi(adapt)) {
- pass = false;
- } else {
- // CIE delta E test with modifications
- float color_scale = 1.0f;
- // ramp down the color test in scotopic regions
- if (adapt < 10.0f) {
- color_scale = 1.0f - (10.0f - color_scale) / 10.0f;
- color_scale = color_scale * color_scale;
- }
- float da = aA[index] - bA[index];
- float db = aB[index] - bB[index];
- da = da * da;
- db = db * db;
- float delta_e = (da + db) * color_scale;
- if (delta_e > factor) {
- pass = false;
- }
- }
- if (!pass) {
- pixels_failed++;
- if (args.ImgDiff) {
- args.ImgDiff->Set(255, 0, 0, 255, index);
- }
- } else {
- if (args.ImgDiff) {
- args.ImgDiff->Set(0, 0, 0, 255, index);
- }
- }
- }
- }
-
- if (aX) delete[] aX;
- if (aY) delete[] aY;
- if (aZ) delete[] aZ;
- if (bX) delete[] bX;
- if (bY) delete[] bY;
- if (bZ) delete[] bZ;
- if (aLum) delete[] aLum;
- if (bLum) delete[] bLum;
- if (la) delete la;
- if (lb) delete lb;
- if (aA) delete aA;
- if (bA) delete bA;
- if (aB) delete aB;
- if (bB) delete bB;
-
- return (unsigned long)pixels_failed;
-
-}
+++ /dev/null
-#ifndef PDIFF_H_
-#define PDIFF_H_
-
-/*
-Copyright (C) 2006 Yangli Hector Yee
-
-This program is free software; you can redistribute it and/or modify it under the terms of the
-GNU General Public License as published by the Free Software Foundation; either version 2 of the License,
-or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this program;
-if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Code from http://pdiff.sourceforge.net
-*/
-
-class RGBAImage
-{
-public:
- virtual int Get_Width(void) const = 0;
- virtual int Get_Height(void) const = 0;
- virtual unsigned char Get_Red(unsigned int i) = 0;
- virtual unsigned char Get_Green(unsigned int i) = 0;
- virtual unsigned char Get_Blue(unsigned int i) = 0;
- virtual unsigned char Get_Alpha(unsigned int i) = 0;
- virtual void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i) = 0;
- virtual unsigned int Get(int i) const = 0;
-};
-
-class RGBAImageData : RGBAImage
-{
-public:
- RGBAImageData(int w, int h)
- {
- Width = w;
- Height = h;
- Data = new unsigned int[w * h];
- };
- ~RGBAImageData() { if (Data) delete[] Data; }
- unsigned char Get_Red(unsigned int i) { return (Data[i] & 0xFF); }
- unsigned char Get_Green(unsigned int i) { return ((Data[i]>>8) & 0xFF); }
- unsigned char Get_Blue(unsigned int i) { return ((Data[i]>>16) & 0xFF); }
- unsigned char Get_Alpha(unsigned int i) { return ((Data[i]>>24) & 0xFF); }
- void Set(unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned int i)
- { Data[i] = r | (g << 8) | (b << 16) | (a << 24); }
- int Get_Width(void) const { return Width; }
- int Get_Height(void) const { return Height; }
- void Set(int x, int y, unsigned int d) { Data[x + y * Width] = d; }
- unsigned int Get(int x, int y) const { return Data[x + y * Width]; }
- unsigned int Get(int i) const { return Data[i]; }
-
-protected:
- int Width;
- int Height;
- unsigned int * Data;
-};
-
-class CompareArgs {
-public:
- CompareArgs();
- ~CompareArgs();
-
- RGBAImage *ImgA;
- RGBAImage *ImgB;
- RGBAImage *ImgDiff;
- float FieldOfView; // Field of view in degrees
- float Gamma; // The gamma to convert to linear color space
- float Luminance; // the display's luminance
-};
-
-#define DIFFERENT_SIZES (unsigned long)-1
-#define IDENTICAL (unsigned long)0
-
-unsigned long Yee_Compare(CompareArgs &args);
-
-#endif
-
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "base_util.h"
-#include "tstr_util.h"
-#include "prefs_util.h"
-#include "netstr.h"
-
-/* length of PT_*_PREFIX string in characters. All should have the same length */
-#define TYPE_PREFIX_CCH_LEN 2
-
-/* when we serialize names of variables, we prepend name with the following
- type indentifiers */
-#define PT_INT_PREFIX _T("i ")
-#define PT_STRING_PREFIX _T("s ")
-
-static int pref_type_valid(pref_type type)
-{
- if (PT_INT == type)
- return TRUE;
- if (PT_STRING == type)
- return TRUE;
- return FALSE;
-}
-
-/* Given a string value 'txt' and it's type 'type', return a string that
- encodes type within a string */
-TCHAR *pref_tstr_with_type(const TCHAR *txt, pref_type type)
-{
- if (PT_INT == type)
- return tstr_cat(PT_INT_PREFIX, txt);
- else if (PT_STRING == type)
- return tstr_cat(PT_STRING_PREFIX, txt);
- else
- assert(0);
- return NULL;
-}
-
-/* Serialize 'pref' to a buffer 'buf_ptr' of size 'buf_len_cb_ptr'.
- Return TRUE if ok, FALSE if failed (e.g. buffer is not large enough).
- If 'buf_ptr' is NULL, returns desired size in 'buf_len_cb_ptr'.
- */
-static int prefs_serialize_pref(prefs_data *pref, TCHAR **buf_ptr, size_t *buf_len_cb_ptr)
-{
- size_t len_cb;
- TCHAR * name_with_type;
- int f_ok;
-
- assert(pref);
- assert(pref->name);
- assert(pref_type_valid(pref->type));
- assert(buf_len_cb_ptr);
-
- if (!buf_ptr) {
- len_cb = netstr_tstrn_serialized_len_cb(TYPE_PREFIX_CCH_LEN + tstr_len(pref->name));
- if (PT_INT == pref->type)
- len_cb += netstr_int_serialized_len_cb(*pref->data.data_int);
- else if (PT_STRING == pref->type)
- len_cb += netstr_tstr_serialized_len_cb(*pref->data.data_str);
- else
- assert(0);
- *buf_len_cb_ptr = len_cb;
- return TRUE;
- }
-
- name_with_type = pref_tstr_with_type(pref->name, pref->type);
- if (!name_with_type) return FALSE;
- f_ok = netstr_tstr_serialize(name_with_type, buf_ptr, buf_len_cb_ptr);
- free((void*)name_with_type);
- if (!f_ok)
- return FALSE;
-
- if (PT_INT == pref->type)
- f_ok = netstr_int_serialize(*pref->data.data_int, buf_ptr, buf_len_cb_ptr);
- else if (PT_STRING == pref->type)
- f_ok = netstr_tstr_serialize(*pref->data.data_str, buf_ptr, buf_len_cb_ptr);
- else
- assert(0);
-
- if (!f_ok)
- return FALSE;
-
- return TRUE;
-}
-
-/* Return the size of memory required to serialize 'pref' data */
-static size_t prefs_serialized_pref_cb_len(prefs_data *pref)
-{
- int f_ok;
- size_t len;
-
- f_ok = prefs_serialize_pref(pref, NULL, &len);
- if (!f_ok)
- return 0;
- return len;
-}
-
-/* Serialize 'prefs' as string. Returns newly allocated string and
- length, in bytes, of string in '*tstr_len_cb_ptr' (not including
- terminating zero). 'tstr_len_cb_ptr' can be NULL.
- Returns NULL on error.
- Caller needs to free() the result */
-TCHAR *prefs_to_tstr(prefs_data *prefs, size_t *tstr_len_cb_ptr)
-{
- int i = 0;
- size_t total_serialized_len_cb = 0;
- size_t len_cb;
- int f_ok;
- TCHAR * serialized = NULL;
- TCHAR * tmp;
- size_t tmp_len_cb;
-
- /* calculate the size of buffer required to serialize 'prefs' */
- while (prefs[i].name) {
- len_cb = prefs_serialized_pref_cb_len(&(prefs[i]));
- assert(len_cb > 0);
- total_serialized_len_cb += len_cb;
- ++i;
- }
-
- if (0 == total_serialized_len_cb)
- return NULL;
-
- /* allocate the buffer and serialize to it */
- serialized = (TCHAR*)malloc(total_serialized_len_cb+sizeof(TCHAR));
- if (!serialized) return NULL;
- tmp = serialized;
- tmp_len_cb = total_serialized_len_cb;
- i = 0;
- while (prefs[i].name) {
- f_ok = prefs_serialize_pref(&(prefs[i]), &tmp, &tmp_len_cb);
- assert(f_ok);
- assert(tmp_len_cb >= 0);
- ++i;
- }
- assert(0 == tmp_len_cb);
- *tmp = 0;
- if (tstr_len_cb_ptr)
- *tstr_len_cb_ptr = total_serialized_len_cb;
- return serialized;
-}
-
-/* Find a variable with a given 'name' and 'type' in 'prefs' array */
-prefs_data *prefs_find_by_name_type(prefs_data *prefs, const TCHAR *name, pref_type type)
-{
- int i = 0;
- while (prefs[i].name) {
- if ((prefs[i].type == type) && (tstr_ieq(name, prefs[i].name))) {
- return &(prefs[i]);
- }
- ++i;
- }
- return NULL;
-}
-
-/* Incrementally parse one serialized variable in a string '*str_ptr' of
- remaining size '*str_len_cb_ptr'.
- It reads name, type and value of the variable from the string and
- updates 'prefs' slot with this name/type with this value. If slot
- with a given name/type doesn't exist, nothing happens.
- It updates the '*str_ptr' and '*str_len_cb_ptr' to reflect consuming
- the part that contained one variable. The idea is to call it in a
- loop until '*str_len_cb_ptr' reaches 0.
- Returns FALSE on error. */
-static int prefs_parse_item(prefs_data *prefs, const TCHAR **str_ptr, size_t *str_len_cb_ptr)
-{
- const TCHAR * name_with_type = NULL;
- const TCHAR * name;
- size_t str_len_cch;
- const TCHAR * value_str = NULL;
- int value_int;
- int f_ok;
- pref_type type;
- prefs_data * pref;
-
- assert(str_ptr);
- if (!str_ptr) return FALSE;
- assert(str_len_cb_ptr);
- if (!str_len_cb_ptr) return FALSE;
-
- f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &name_with_type, &str_len_cch);
- if (!f_ok)
- goto Error;
-
- if (tstr_startswithi(name_with_type, PT_INT_PREFIX))
- type = PT_INT;
- else if (tstr_startswithi(name_with_type, PT_STRING_PREFIX))
- type = PT_STRING;
- else {
- assert(0);
- goto Error;
- }
- /* skip the type prefix */
- name = name_with_type + TYPE_PREFIX_CCH_LEN;
-
- pref = prefs_find_by_name_type(prefs, name, type);
-
- if (PT_STRING == type)
- f_ok = netstr_parse_str(str_ptr, str_len_cb_ptr, &value_str, &str_len_cch);
- else if (PT_INT == type)
- f_ok = netstr_parse_int(str_ptr, str_len_cb_ptr, &value_int);
- else {
- assert(0);
- goto Error;
- }
- if (!f_ok)
- goto Error;
-
- if (!pref) {
- /* it's ok to not have a given preference e.g. when changing version some of the
- preferences might go away. But we still want to be notified about that during
- developement, since it's unlikely thing to happen */
- assert(0);
- goto Exit;
- }
-
- if (PT_INT == type)
- *pref->data.data_int = value_int;
- else if (PT_STRING == type) {
- /* taking memory ownership */
- *pref->data.data_str = (TCHAR*)value_str;
- value_str = NULL;
- } else {
- assert(0);
- goto Error;
- }
-
-Exit:
- free((void*)name_with_type);
- free((void*)value_str);
- return TRUE;
-Error:
- free((void*)name_with_type);
- free((void*)value_str);
- return FALSE;
-}
-
-int prefs_from_tstr(prefs_data *prefs, const TCHAR *str, size_t str_len_cch)
-{
- int f_ok;
- size_t str_len_cb;
-
- assert(str);
- if (!str) return FALSE;
-
- if (-1 == str_len_cch)
- str_len_cch = tstr_len(str);
-
- str_len_cb = str_len_cch * sizeof(TCHAR);
- while (0 != str_len_cb) {
- f_ok = prefs_parse_item(prefs, &str, &str_len_cb);
- if (!f_ok)
- return FALSE;
- }
- assert(0 == str_len_cb);
- return TRUE;
-}
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef PREFS_H_
-#define PREFS_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef enum pref_type pref_type;
-enum pref_type {
- PT_INVALID = 0,
- PT_INT,
- PT_STRING
-};
-
-typedef struct prefs_data prefs_data;
-
-/* describes all preferences in a program */
-struct prefs_data {
- const TCHAR * name;
- pref_type type;
- union {
- void * data_void;
- int * data_int;
- TCHAR ** data_str;
- } data;
-};
-
-TCHAR *prefs_to_tstr(prefs_data *prefs, size_t *tstr_len_cb_ptr);
-int prefs_from_tstr(prefs_data *prefs, const TCHAR *str, size_t str_len_cb);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef __STR_STRSAFE_H
-#define __STR_STRSAFE_H
-
-/* When using MSVC, use <strsafe.h>, emulate it on other compiler (e.g. mingw) */
-
-#ifndef __GNUC__
- #include <strsafe.h>
-#else
- #include <stdio.h>
- #include <string.h>
- #include <windows.h>
- #define STRSAFE_E_INSUFFICIENT_BUFFER -1
- #define _vsnprintf_s(p,s,z,f,a) vsnprintf(p,s,f,a)
- #define StringCchVPrintfA vsnprintf
- #define StringCchPrintfA snprintf
- #define _stricmp strcasecmp
- #define _strnicmp strncasecmp
-#endif
-
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-
-/* The most basic things, including string handling functions */
-#include "base_util.h"
-#include "str_util.h"
-#include "str_strsafe.h"
-
-/* TODO: should probably be based on MSVC version */
-#if defined(__GNUC__) || !defined(_WIN32) || (_MSC_VER < 1400)
-void strcpy_s(char *dst, size_t dstLen, const char *src)
-{
- size_t toCopy;
-
- assert(dst);
- assert(src);
- assert(dstLen > 0);
-
- if (!dst || !src || dstLen <= 0)
- return;
-
- toCopy = strlen(src);
- if (toCopy > (dstLen-1))
- toCopy = dstLen - 1;
-
- strncpy(dst, src, toCopy);
- dst[toCopy] = 0;
-}
-#endif
-
-void no_op(void)
-{
- /* This really is a no-op, just to silence the compiler */
-}
-
-int char_is_ws_or_zero(char c)
-{
- switch (c) {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- case 0:
- return TRUE;
- }
- return FALSE;
-}
-
-int char_is_ws(char c)
-{
- switch (c) {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- return TRUE;
- }
- return FALSE;
-}
-
-int char_is_digit(char c)
-{
- if ((c >= '0') && (c <= '9'))
- return TRUE;
- return FALSE;
-}
-
-/* Concatenate 4 strings. Any string can be NULL.
- Caller needs to free() memory. */
-char *str_cat4(const char *str1, const char *str2, const char *str3, const char *str4)
-{
- char *str;
- char *tmp;
- size_t str1_len = 0;
- size_t str2_len = 0;
- size_t str3_len = 0;
- size_t str4_len = 0;
-
- if (str1)
- str1_len = strlen(str1);
- if (str2)
- str2_len = strlen(str2);
- if (str3)
- str3_len = strlen(str3);
- if (str4)
- str4_len = strlen(str4);
-
- str = (char*)zmalloc(str1_len + str2_len + str3_len + str4_len + 1);
- if (!str)
- return NULL;
-
- tmp = str;
- if (str1) {
- memcpy(tmp, str1, str1_len);
- tmp += str1_len;
- }
- if (str2) {
- memcpy(tmp, str2, str2_len);
- tmp += str2_len;
- }
- if (str3) {
- memcpy(tmp, str3, str3_len);
- tmp += str3_len;
- }
- if (str4) {
- memcpy(tmp, str4, str1_len);
- }
- return str;
-}
-
-/* Concatenate 3 strings. Any string can be NULL.
- Caller needs to free() memory. */
-char *str_cat3(const char *str1, const char *str2, const char *str3)
-{
- return str_cat4(str1, str2, str3, NULL);
-}
-
-/* Concatenate 2 strings. Any string can be NULL.
- Caller needs to free() memory. */
-char *str_cat(const char *str1, const char *str2)
-{
- return str_cat4(str1, str2, NULL, NULL);
-}
-
-char *str_dup(const char *str)
-{
- return str_cat4(str, NULL, NULL, NULL);
-}
-
-char *str_dupn(const char *str, size_t str_len_cch)
-{
- char *copy;
-
- if (!str)
- return NULL;
- copy = (char*)malloc(str_len_cch+1);
- if (!copy)
- return NULL;
- memcpy(copy, str, str_len_cch);
- copy[str_len_cch] = 0;
- return copy;
-}
-
-int str_copyn(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size)
-{
- char *end = dst + dst_cch_size - 1;
- if (0 == dst_cch_size) {
- if (0 == src_cch_size)
- return TRUE;
- else
- return FALSE;
- }
-
- while ((dst < end) && (src_cch_size > 0)) {
- *dst++ = *src++;
- --src_cch_size;
- }
- *dst = 0;
- if (0 == src_cch_size)
- return TRUE;
- else
- return FALSE;
-}
-
-int str_copy(char *dst, size_t dst_cch_size, const char *src)
-{
- char *end = dst + dst_cch_size - 1;
- if (0 == dst_cch_size)
- return FALSE;
-
- while ((dst < end) && *src) {
- *dst++ = *src++;
- }
- *dst = 0;
- if (0 == *src)
- return TRUE;
- else
- return FALSE;
-}
-
-int str_eq(const char *str1, const char *str2)
-{
- if (!str1 && !str2)
- return TRUE;
- if (!str1 || !str2)
- return FALSE;
- if (0 == strcmp(str1, str2))
- return TRUE;
- return FALSE;
-}
-
-int str_ieq(const char *str1, const char *str2)
-{
- if (!str1 && !str2)
- return TRUE;
- if (!str1 || !str2)
- return FALSE;
- if (0 == _stricmp(str1, str2))
- return TRUE;
- return FALSE;
-}
-
-int str_eqn(const char *str1, const char *str2, int len)
-{
- if (!str1 && !str2)
- return TRUE;
- if (!str1 || !str2)
- return FALSE;
- if (0 == strncmp(str1, str2, len))
- return TRUE;
- return FALSE;
-}
-
-/* return true if 'str' starts with 'txt', case-sensitive */
-int str_startswith(const char *str, const char *txt)
-{
- if (!str && !txt)
- return TRUE;
- if (!str || !txt)
- return FALSE;
-
- if (0 == strncmp(str, txt, strlen(txt)))
- return TRUE;
- return FALSE;
-}
-
-/* return true if 'str' starts with 'txt', NOT case-sensitive */
-int str_startswithi(const char *str, const char *txt)
-{
- if (!str && !txt)
- return TRUE;
- if (!str || !txt)
- return FALSE;
-
- if (0 == _strnicmp(str, txt, strlen(txt)))
- return TRUE;
- return FALSE;
-}
-
-int str_endswith(const char *txt, const char *end)
-{
- size_t end_len;
- size_t txt_len;
-
- if (!txt || !end)
- return FALSE;
-
- txt_len = strlen(txt);
- end_len = strlen(end);
- if (end_len > txt_len)
- return FALSE;
- if (str_eq(txt+txt_len-end_len, end))
- return TRUE;
- return FALSE;
-}
-
-int str_endswithi(const char *txt, const char *end)
-{
- size_t end_len;
- size_t txt_len;
-
- if (!txt || !end)
- return FALSE;
-
- txt_len = strlen(txt);
- end_len = strlen(end);
- if (end_len > txt_len)
- return FALSE;
- if (str_ieq(txt+txt_len-end_len, end))
- return TRUE;
- return FALSE;
-}
-
-int str_endswith_char(const char *str, char c)
-{
- char end[2];
- end[0] = c;
- end[1] = 0;
- return str_endswith(str, end);
-}
-
-int str_empty(const char *str)
-{
- if (!str)
- return TRUE;
- if (0 == *str)
- return TRUE;
- return FALSE;
-}
-
-/* Find character 'c' in string 'txt'.
- Return pointer to this character or NULL if not found */
-const char *str_find_char(const char *txt, char c)
-{
- while (*txt != c) {
- if (0 == *txt)
- return NULL;
- ++txt;
- }
- return txt;
-}
-
-/* split a string '*txt' at the border character 'c'. Something like python's
- string.split() except called iteratively.
- Returns a copy of the string (must be free()d by the caller).
- Returns NULL to indicate there's no more items. */
-char *str_split_iter(char **txt, char c)
-{
- const char *tmp;
- const char *pos;
- char *result;
-
- tmp = (const char*)*txt;
- if (!tmp)
- return NULL;
-
- pos = str_find_char(tmp, c);
- if (pos) {
- result = str_dupn(tmp, (int)(pos-tmp));
- *txt = (char*)pos+1;
- } else {
- result = str_dup(tmp);
- *txt = NULL; /* next iteration will return NULL */
- }
- return result;
-}
-
-/* Replace all posible versions (Unix, Windows, Mac) of newline character
- with 'replace'. Returns newly allocated string with normalized newlines
- or NULL if error.
- Caller needs to free() the result */
-char *str_normalize_newline(const char *txt, const char *replace)
-{
- size_t replace_len;
- char c;
- char * result;
- const char * tmp;
- char * tmp_out;
- size_t result_len = 0;
-
- replace_len = strlen(replace);
- tmp = txt;
- for (;;) {
- c = *tmp++;
- if (!c)
- break;
- if (0xa == c) {
- /* a single 0xa => Unix */
- result_len += replace_len;
- } else if (0xd == c) {
- if (0xa == *tmp) {
- /* 0xd 0xa => dos */
- result_len += replace_len;
- ++tmp;
- }
- else {
- /* just 0xd => Mac */
- result_len += replace_len;
- }
- } else
- ++result_len;
- }
-
- if (0 == result_len)
- return NULL;
-
- result = (char*)malloc(result_len+1);
- if (!result)
- return NULL;
- tmp_out = result;
- for (;;) {
- c = *txt++;
- if (!c)
- break;
- if (0xa == c) {
- /* a single 0xa => Unix */
- memcpy(tmp_out, replace, replace_len);
- tmp_out += replace_len;
- } else if (0xd == c) {
- if (0xa == *txt) {
- /* 0xd 0xa => dos */
- memcpy(tmp_out, replace, replace_len);
- tmp_out += replace_len;
- ++txt;
- }
- else {
- /* just 0xd => Mac */
- memcpy(tmp_out, replace, replace_len);
- tmp_out += replace_len;
- }
- } else
- *tmp_out++ = c;
- }
-
- *tmp_out = 0;
- return result;
-}
-
-#define WHITE_SPACE_CHARS " \n\t\r"
-
-/* Strip all 'to_strip' characters from the beginning of the string.
- Does stripping in-place */
-void str_strip_left(char *txt, const char *to_strip)
-{
- char *new_start = txt;
- char c;
- if (!txt || !to_strip)
- return;
- for (;;) {
- c = *new_start;
- if (0 == c)
- break;
- if (!str_contains(to_strip, c))
- break;
- ++new_start;
- }
-
- if (new_start != txt) {
- memmove(txt, new_start, strlen(new_start)+1);
- }
-}
-
-/* Strip white-space characters from the beginning of the string.
- Does stripping in-place */
-void str_strip_ws_left(char *txt)
-{
- str_strip_left(txt, WHITE_SPACE_CHARS);
-}
-
-void str_strip_right(char *txt, const char *to_strip)
-{
- char * new_end;
- char c;
- if (!txt || !to_strip)
- return;
- if (0 == *txt)
- return;
- /* point at the last character in the string */
- new_end = txt + strlen(txt) - 1;
- for (;;) {
- c = *new_end;
- if (!str_contains(to_strip, c))
- break;
- if (txt == new_end)
- break;
- --new_end;
- }
- if (str_contains(to_strip, *new_end))
- new_end[0] = 0;
- else
- new_end[1] = 0;
-}
-
-void str_strip_ws_right(char *txt)
-{
- str_strip_right(txt, WHITE_SPACE_CHARS);
-}
-
-void str_strip_both(char *txt, const char *to_strip)
-{
- str_strip_left(txt, to_strip);
- str_strip_right(txt, to_strip);
-}
-
-void str_strip_ws_both(char *txt)
-{
- str_strip_ws_left(txt);
- str_strip_ws_right(txt);
-}
-
-#if 0
-int utf8_eq(const utf8* str1, const utf8* str2)
-{
- return str_eq(str1, str2);
-}
-
-int utf8_eqn(const utf8* str1, const utf8* str2, int len)
-{
- return str_eqn(str1, str2, len);
-}
-
-int utf8_copy(utf8 *dst, int dst_size_bytes, utf8* src)
-{
- return str_copy(dst, dst_size_bytes, src);
-}
-
-utf8 *utf8_dup(const utf8 *str)
-{
- return str_dup(str);
-}
-
-utf8 *utf8_cat4(const utf8 *str1, const utf8 *str2, const utf8 *str3, const utf8 *str4)
-{
- return str_cat4(str1, str2, str3, str4);
-}
-
-utf8 *utf8_cat3(const utf8 *str1, const utf8 *str2, const utf8 *str3)
-{
- return str_cat4(str1, str2, str3, NULL);
-}
-
-utf8 *utf8_cat(const utf8 *str1, const utf8 *str2)
-{
- return str_cat4(str1, str2, NULL, NULL);
-}
-
-int utf8_endswith(const utf8 *str, const utf8 *end)
-{
- return str_endswith(str, end);
-}
-#endif
-
-#define HEX_NUMBERS "0123456789ABCDEF"
-static void char_to_hex(unsigned char c, char* buffer)
-{
- buffer[0] = HEX_NUMBERS[c / 16];
- buffer[1] = HEX_NUMBERS[c % 16];
-}
-
-int str_contains(const char *str, char c)
-{
- const char *pos = str_find_char(str, c);
- if (!pos)
- return FALSE;
- return TRUE;
-}
-
-#define CHAR_URL_DONT_ENCODE "-_.!~*'()"
-
-int char_needs_url_encode(char c)
-{
- if ((c >= 'a') && (c <= 'z'))
- return FALSE;
- if ((c >= 'A') && (c <= 'Z'))
- return FALSE;
- if ((c >= '0') && (c <= '9'))
- return FALSE;
- if (str_contains(CHAR_URL_DONT_ENCODE, c))
- return FALSE;
- return TRUE;
-}
-
-/* url-encode 'str'. Returns NULL in case of error. Caller needs to free()
- the result */
-char *str_url_encode(const char *str)
-{
- char * encoded;
- char * result;
- int res_len = 0;
- const char * tmp = str;
-
- /* calc the size of the string after url encoding */
- while (*tmp) {
- if (char_needs_url_encode(*tmp))
- res_len += 3;
- else
- ++res_len;
- tmp++;
- }
- if (0 == res_len)
- return NULL;
-
- encoded = (char*)malloc(res_len+1);
- if (!encoded)
- return NULL;
-
- result = encoded;
- tmp = str;
- while (*tmp) {
- if (char_needs_url_encode(*tmp)) {
- *encoded++ = '%';
- char_to_hex(*tmp, encoded);
- encoded += 2;
- } else {
- if (' ' == *tmp)
- *encoded++ = '+';
- else
- *encoded++ = *tmp;
- }
- tmp++;
- }
- *encoded = 0;
- return result;
-}
-
-char *str_escape(const char *txt)
-{
- /* TODO: */
- return str_dup(txt);
-}
-
-char *str_printf(const char *format, ...)
-{
- char *result;
- va_list args;
- va_start(args, format);
- result = str_printf_args(format, args);
- va_end(args);
- return result;
-}
-
-char *str_printf_args(const char *format, va_list args)
-{
-#ifdef _WIN32
- HRESULT hr;
- char message[256];
- char * buf;
- size_t bufCchSize;
- char * result = NULL;
-
- buf = &(message[0]);
- bufCchSize = sizeof(message);
-
- for (;;)
- {
- /* TODO: this only works on windows with recent C library */
- hr = StringCchVPrintfA(buf, bufCchSize, format, args);
- if (S_OK == hr)
- break;
- if (STRSAFE_E_INSUFFICIENT_BUFFER != hr)
- {
- /* any error other than buffer not big enough:
- a) should not happen
- b) means we give up */
- assert(FALSE);
- goto Error;
- }
- /* we have to make the buffer bigger. The algorithm used to calculate
- the new size is arbitrary (aka. educated guess) */
- if (buf != &(message[0]))
- free(buf);
- if (bufCchSize < 4*1024)
- bufCchSize += bufCchSize;
- else
- bufCchSize += 1024;
- buf = (char *)malloc(bufCchSize*sizeof(char));
- if (NULL == buf)
- goto Error;
- }
-
- /* free the buffer if it was dynamically allocated */
- if (buf == &(message[0]))
- return str_dup(buf);
-
- return buf;
-Error:
- if (buf != &(message[0]))
- free((void*)buf);
-
- return NULL;
-#else
- char* buf;
- int len = vasprintf(&buf, format, args);
- return buf;
-#endif
-}
-
-#ifdef _WIN32
-void win32_dbg_out(const char *format, ...)
-{
- char buf[4096];
- char * p = buf;
- int written;
- va_list args;
-
- va_start(args, format);
- written = _vsnprintf(p,sizeof(buf), format, args);
-/* printf(buf);
- fflush(stdout); */
- OutputDebugStringA(buf);
- va_end(args);
-}
-
-void win32_dbg_out_hex(const char *dsc, const unsigned char *data, int dataLen)
-{
- unsigned char buf[64+1];
- unsigned char * curPos;
- int bufCharsLeft;
-
- if (dsc) win32_dbg_out(dsc); /* a bit dangerous if contains formatting codes */
- if (!data) return;
-
- bufCharsLeft = sizeof(buf)-1;
- curPos = buf;
- while (dataLen > 0) {
- if (bufCharsLeft <= 1) {
- *curPos = 0;
- win32_dbg_out((char*)buf);
- bufCharsLeft = sizeof(buf)-1;
- curPos = buf;
- }
- char_to_hex(*data, curPos);
- curPos += 2;
- bufCharsLeft -= 2;
- --dataLen;
- ++data;
- }
-
- if (curPos != buf) {
- *curPos = 0;
- win32_dbg_out(buf);
- }
- win32_dbg_out("\n");
-}
-#endif
-
-/* Given a pointer to a string in '*txt', skip past whitespace in the string
- and put the result in '*txt' */
-void str_skip_ws(char **txtInOut)
-{
- char *cur;
- if (!txtInOut)
- return;
- cur = *txtInOut;
- if (!cur)
- return;
- while (char_is_ws(*cur)) {
- ++cur;
- }
- *txtInOut = cur;
-}
-
-char *str_parse_quoted(char **txt)
-{
- char * strStart;
- char * strCopy;
- char * cur;
- char * dst;
- char c;
- size_t len;
-
- assert(txt);
- if (!txt) return NULL;
- strStart = *txt;
- assert(strStart);
- if (!strStart) return NULL;
-
- assert('"' == *strStart);
- /* TODO: rewrite as 2-phase logic so that counting and copying are always in sync */
- ++strStart;
- cur = strStart;
- len = 0;
- for (;;) {
- c = *cur;
- if ((0 == c) || ('"' == c))
- break;
- if ('\\' == c) {
- /* TODO: should I un-escape more than '"' ?
- I used to un-escape '\' as well, but it wasn't right and
- files with UNC path like "\\foo\file.pdf" failed to load */
- if ('"' == cur[1]) {
- ++cur;
- c = *cur;
- }
- }
- ++cur;
- ++len;
- }
-
- strCopy = (char*)malloc(len+1);
- if (!strCopy)
- return NULL;
-
- cur = strStart;
- dst = strCopy;
- for (;;) {
- c = *cur;
- if (0 == c)
- break;
- if ('"' == c) {
- ++cur;
- break;
- }
- if ('\\' == c) {
- /* TODO: should I un-escape more than '"' ?
- I used to un-escape '\' as well, but it wasn't right and
- files with UNC path like "\\foo\file.pdf" failed to load */
- if ('"' == cur[1]) {
- ++cur;
- c = *cur;
- }
- }
- *dst++ = c;
- ++cur;
- }
- *dst = 0;
- *txt = cur;
- return strCopy;
-}
-
-char *str_parse_non_quoted(char **txt)
-{
- char * cur;
- char * strStart;
- char * strCopy;
- char c;
- size_t strLen;
-
- strStart = *txt;
- assert(strStart);
- if (!strStart) return NULL;
- assert('"' != *strStart);
- cur = strStart;
- for (;;) {
- c = *cur;
- if (char_is_ws_or_zero(c))
- break;
- ++cur;
- }
-
- strLen = cur - strStart;
- assert(strLen > 0);
- strCopy = str_dupn(strStart, strLen);
- *txt = cur;
- return strCopy;
-}
-
-/* 'txt' is path that can be:
- - escaped, in which case it starts with '"', ends with '"' and each '"' that is part of the name is escaped
- with '\'
- - unescaped, in which case it start with != '"' and ends with ' ' or eol (0)
- This function extracts escaped or unescaped path from 'txt'. Returns NULL in case of error.
- Caller needs to free() the result. */
-char *str_parse_possibly_quoted(char **txt)
-{
- char * cur;
- char * str_copy;
-
- if (!txt)
- return NULL;
- cur = *txt;
- if (!cur)
- return NULL;
-
- str_skip_ws(&cur);
- if (0 == *cur)
- return NULL;
- if ('"' == *cur)
- str_copy = str_parse_quoted(&cur);
- else
- str_copy = str_parse_non_quoted(&cur);
- *txt = cur;
- return str_copy;
-}
-
-void str_array_init(str_array *str_arr)
-{
- assert(str_arr);
- if (!str_arr) return;
- memzero(str_arr, sizeof(str_array));
-}
-
-void str_array_free(str_array *str_arr)
-{
- int i;
-
- assert(str_arr);
- if (!str_arr) return;
-
- for (i = 0; i < str_arr->items_count; i++)
- free(str_arr->items[i]);
- free(str_arr->items);
- str_array_init(str_arr);
-}
-
-void str_array_delete(str_array *str_arr)
-{
- assert(str_arr);
- if (!str_arr) return;
- str_array_free(str_arr);
- free((void*)str_arr);
-}
-
-str_item *str_array_get(str_array *str_arr, int index)
-{
- assert(str_arr);
- if (!str_arr) return NULL;
- assert(index >= 0);
- assert(index < str_arr->items_count);
- if ((index < 0) || (index >= str_arr->items_count))
- return NULL;
- return str_arr->items[index];
-}
-
-int str_array_get_count(str_array *str_arr)
-{
- assert(str_arr);
- if (!str_arr) return 0;
- return str_arr->items_count;
-}
-
-/* Set one string at position 'index' in 'str_arr'. Space for the item
- must already be allocated. */
-str_item *str_array_set(str_array *str_arr, int index, const char *str)
-{
- str_item * new_item;
- size_t str_len_cch;
-
- assert(str_arr);
- if (!str_arr) return NULL;
-
- if (index >= str_arr->items_count)
- return NULL;
-
- str_len_cch = str_len(str);
- new_item = (str_item*)malloc(sizeof(str_item) + str_len_cch*sizeof(char));
- if (!new_item)
- return NULL;
- str_copy(new_item->str, str_len_cch+1, str);
- if (str_arr->items[index])
- free(str_arr->items[index]);
- str_arr->items[index] = new_item;
- return new_item;
-}
-
-#define STR_ARR_GROW_VALUE 32
-
-/* make a generic array alloc */
-str_item *str_array_add(str_array *str_arr, const char *str)
-{
- str_item ** tmp;
- str_item * new_item;
- void * data;
- int n;
-
- if (str_arr->items_count >= str_arr->items_allocated) {
- /* increase memory for items if necessary */
- n = str_arr->items_allocated + STR_ARR_GROW_VALUE;
- tmp = (str_item**)realloc(str_arr->items, n * sizeof(str_item *));
- if (!tmp)
- return NULL;
- str_arr->items = tmp;
- data = &(str_arr->items[str_arr->items_count]);
- memzero(data, STR_ARR_GROW_VALUE * sizeof(str_item *));
- str_arr->items_allocated = n;
- }
- str_arr->items_count++;
- new_item = str_array_set(str_arr, str_arr->items_count - 1, str);
- if (!new_item)
- --str_arr->items_count;
- return new_item;
-}
-
-int str_array_exists_no_case(str_array *str_arr, const char *str)
-{
- int count, i;
- str_item * item;
- char * item_str;
-
- if (!str_arr || !str)
- return FALSE;
-
- count = str_arr->items_count;
- for (i = 0; i < count; i++)
- {
- item = str_arr->items[i];
- item_str = item->str;
- if (str_ieq(str, item_str))
- return TRUE;
- }
- return FALSE;
-}
-
-str_item *str_array_add_no_dups(str_array *str_arr, const char *str)
-{
- if (str_array_exists_no_case(str_arr, str))
- return NULL;
-
- return str_array_add(str_arr, str);
-}
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef STR_UTIL_H_
-#define STR_UTIL_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* DOS is 0xd 0xa */
-#define DOS_NEWLINE "\x0d\x0a"
-/* Mac is single 0xd */
-#define MAC_NEWLINE "\x0d"
-/* Unix is single 0xa (10) */
-#define UNIX_NEWLINE "\x0a"
-#define UNIX_NEWLINE_C 0xa
-
-#ifdef _WIN32
- #define DIR_SEP_CHAR '\\'
- #define DIR_SEP_STR "\\"
-#else
- #define DIR_SEP_CHAR '/'
- #define DIR_SEP_STR "/"
-#endif
-
-void no_op(void);
-
-#ifdef DEBUG
- #ifdef _WIN32
- #define DBG_OUT win32_dbg_out
- #define DBG_OUT_HEX win32_dbg_out_hex
- #else
- #define DBG_OUT printf
- #define DBG_OUT_HEX(...) no_op()
- #endif
-#else
- #define DBG_OUT(...) no_op()
- #define DBG_OUT_HEX(...) no_op()
-#endif
-
-int char_is_ws_or_zero(char c);
-int char_is_ws(char c);
-int char_is_digit(char c);
-
-/* TODO: should probably be based on MSVC version */
-#if defined(__GNUC__) || !defined(_WIN32) || (_MSC_VER < 1400)
-void strcpy_s(char *dst, size_t dstLen, const char *src);
-#endif
-
-#define str_len strlen
-int str_eq(const char *str1, const char *str2);
-int str_ieq(const char *str1, const char *str2);
-#define str_eq_no_case str_ieq
-int str_eqn(const char *str1, const char *str2, int len);
-int str_startswith(const char *str, const char *txt);
-int str_startswithi(const char *str, const char *txt);
-int str_endswith(const char *str, const char *end);
-int str_endswithi(const char *str, const char *end);
-int str_endswith_char(const char *str, char c);
-int str_empty(const char *str);
-int str_copy(char *dst, size_t dst_cch_size, const char *src);
-int str_copyn(char *dst, size_t dst_cch_size, const char *src, size_t src_cch_size);
-char * str_dup(const char *str);
-char * str_dupn(const char *str, size_t len);
-char * str_cat(const char *str1, const char *str2);
-char * str_cat3(const char *str1, const char *str2, const char *str3);
-char * str_cat4(const char *str1, const char *str2, const char *str3, const char *str4);
-char * str_url_encode(const char *str);
-int char_needs_url_escape(char c);
-int str_contains(const char *str, char c);
-char * str_printf_args(const char *format, va_list args);
-char * str_printf(const char *format, ...);
-const char *str_find_char(const char *txt, char c);
-char * str_split_iter(char **txt, char c);
-char * str_normalize_newline(const char *txt, const char *replace);
-void str_strip_left(char *txt, const char *to_strip);
-void str_strip_ws_left(char *txt);
-void str_strip_right(char *txt, const char *to_strip);
-void str_strip_ws_right(char *txt);
-void str_strip_both(char *txt, const char *to_strip);
-void str_strip_ws_both(char *txt);
-char * str_escape(const char *txt);
-char * str_parse_possibly_quoted(char **txt);
-
-#ifdef DEBUG
-void str_util_test(void);
-#endif
-
-typedef struct str_item str_item;
-typedef struct str_array str_array;
-
-struct str_item {
- void * opaque; /* opaque data that the user can use */
- char str[1];
-};
-
-struct str_array {
- int items_allocated;
- int items_count;
- str_item ** items;
-};
-
-void str_array_init(str_array *str_arr);
-void str_array_free(str_array *str_arr);
-void str_array_delete(str_array *str_arr);
-str_item *str_array_set(str_array *str_arr, int index, const char *str);
-str_item *str_array_add(str_array *str_arr, const char *str);
-str_item *str_array_get(str_array *str_arr, int index);
-int str_array_get_count(str_array *str_arr);
-int str_array_exists_no_case(str_array *str_arr, const char *str);
-str_item *str_array_add_no_dups(str_array *str_arr, const char *str);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "str_util.h"
-
-#ifndef DEBUG
-#define DEBUG 1
-#endif
-
-#define LAST_TXT "last"
-void str_util_test(void)
-{
- char buf[256];
- char * tmp;
-
- assert(!str_endswith(NULL, NULL));
- assert(!str_endswith(NULL, "foo"));
- assert(!str_endswith("bar", NULL));
- assert(!str_endswith("bar", "baru"));
- assert(str_endswith("whammy", "whammy"));
- assert(str_endswith("whammy", "hammy"));
- assert(str_endswith("whammy", "y"));
- assert(str_endswith("whmmy", ""));
- str_copy(buf, sizeof(buf), LAST_TXT);
- str_strip_left(buf, "zot");
- assert(str_eq(buf, LAST_TXT));
- str_strip_right(buf, "zpo");
- assert(str_eq(buf, LAST_TXT));
- str_copy(buf, sizeof(buf), " \n last ");
- str_strip_left(buf, " \n");
- assert(str_eq(buf, "last "));
- str_strip_right(buf, " \n");
- assert(str_eq(buf, LAST_TXT));
- str_copy(buf, sizeof(buf), LAST_TXT);
- str_strip_left(buf, LAST_TXT);
- assert(0 == buf[0]);
- str_copy(buf, sizeof(buf), LAST_TXT);
- str_strip_right(buf, LAST_TXT);
- assert(0 == buf[0]);
- str_copy(buf, sizeof(buf), "\x0d\x0a");
- tmp = str_normalize_newline(buf, UNIX_NEWLINE);
- assert(str_eq(tmp, UNIX_NEWLINE));
- free((void*)tmp);
- tmp = NULL;
-}
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#include "strlist_util.h"
-#include "str_util.h"
-
-int StrList_Len(StrList **root)
-{
- int len = 0;
- StrList * cur;
- assert(root);
- if (!root)
- return 0;
- cur = *root;
- while (cur) {
- ++len;
- cur = cur->next;
- }
- return len;
-}
-
-BOOL StrList_InsertAndOwn(StrList **root, char *txt)
-{
- StrList * el;
- assert(root && txt);
- if (!root || !txt)
- return FALSE;
-
- el = (StrList*)malloc(sizeof(StrList));
- if (!el)
- return FALSE;
- el->str = txt;
- el->next = *root;
- *root = el;
- return TRUE;
-}
-
-BOOL StrList_Insert(StrList **root, char *txt)
-{
- char *txtDup;
-
- assert(root && txt);
- if (!root || !txt)
- return FALSE;
- txtDup = str_dup(txt);
- if (!txtDup)
- return FALSE;
-
- if (!StrList_InsertAndOwn(root, txtDup)) {
- free((void*)txtDup);
- return FALSE;
- }
- return TRUE;
-}
-
-void StrList_Destroy(StrList **root)
-{
- StrList * cur;
- StrList * next;
-
- if (!root)
- return;
- cur = *root;
- while (cur) {
- next = cur->next;
- free((void*)cur->str);
- free((void*)cur);
- cur = next;
- }
- *root = NULL;
-}
+++ /dev/null
-/* Written by Krzysztof Kowalczyk (http://blog.kowalczyk.info)
- The author disclaims copyright to this source code. */
-#ifndef STRLIST_UTIL_H_
-#define STRLIST_UTIL_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct StrList {
- struct StrList * next;
- char * &nbs