Alas, there are not many actual changes, most notable change is addition of regex routines using GNU regex libraries:
http://www.gnu.org/software/libc/manual/html_node/Regular-Expressions.html
\r
Requirements\r
------------\r
-MinGW or compatible GNU C compiler: http://www.mingw.org/\r
-DataFlex 3.2 Console Mode or greater: http://www.dataaccess.com/\r
+MinGW or compatible GNU C compiler: \r
+ http://www.mingw.org/\r
+DataFlex 3.2 Console Mode or greater: \r
+ http://www.dataaccess.com/\r
+For regex functionality requires the GNU posix regex libraries:\r
+ http://sourceforge.net/projects/mingw/files/Other/UserContributed/regex/mingw-regex-2.5.1/mingw-libgnurx-2.5.1-src.tar.gz/download\r
\r
Installation\r
------------\r
\r
Alternatively include the dataflex includes as required directly in dataflex\r
source code.
+\r
+Once everything is built, copy the dataflex .pki and .flp files to the location where\r
+your dataflex setup expects to find it's pkg and flx files. Copy both df32func.dll and\r
+libgnurx-0.dll to a location in your path.\r
# Project: df32func\r
+#\r
+# df32func dll extension for Console Mode DataFlex 3.2\r
+#\r
+# Copyright (c) 2007-2015, glyn@8kb.co.uk\r
+# Author: Glyn Astill <glyn@8kb.co.uk>\r
\r
CC = gcc.exe\r
WINDRES = windres.exe\r
RES = df32func.res\r
-OBJ = df32func.o $(RES)\r
-LINKOBJ = df32func.o $(RES)\r
-LIBS = --no-export-all-symbols --add-stdcall-alias -lwsock32 \r
+OBJ = df32func.o memman.o gnuregex.o $(RES)\r
+LINKOBJ = df32func.o memman.o gnuregex.o $(RES)\r
+LIBS = --no-export-all-symbols --add-stdcall-alias -lwsock32 -lgnurx\r
BIN = df32func.dll\r
CFLAGS = -O2\r
DLLWRAP=dllwrap.exe\r
df32func.o: df32func.c\r
$(CC) -c df32func.c -o df32func.o $(CFLAGS)\r
\r
+memman.o: memman.c\r
+ $(CC) -c memman.c -o memman.o $(CFLAGS)\r
+\r
+gnuregex.o: gnuregex.c\r
+ $(CC) -c gnuregex.c -o gnuregex.o $(CFLAGS)\r
+\r
df32func.res: df32func.rc \r
$(WINDRES) -i df32func.rc --input-format=rc -o $(RES) -O coff \r
* df32func.c\r
* df32func extensions for Console Mode DataFlex 3.2\r
*\r
- * Copyright (c) 2007-2009, glyn@8kb.co.uk\r
+ * Copyright (c) 2007-2015, glyn@8kb.co.uk\r
* Author: Glyn Astill <glyn@8kb.co.uk>\r
*\r
*-------------------------------------------------------------------------\r
*/\r
\r
-#include "df32func.h"\r
#include <windows.h>\r
#include <stdio.h>\r
#include <stdlib.h>\r
#include <winsock.h>\r
+#include <tchar.h>\r
+#include "gnuregex.h"\r
+#include "df32func.h"\r
+\r
+/*\r
+ * Used by GetTzi\r
+ * http://msdn.microsoft.com/en-us/library/ms724253.aspx\r
+ */\r
+typedef struct _REG_TZI_FORMAT\r
+{\r
+ LONG Bias;\r
+ LONG StandardBias;\r
+ LONG DaylightBias;\r
+ SYSTEMTIME StandardDate;\r
+ SYSTEMTIME DaylightDate;\r
+} REG_TZI_FORMAT;\r
\r
SOCKET s, sc; /* Socket handle */\r
\r
return n;\r
}\r
\r
+/*\r
+ * Pull back timezone information from windows registry\r
+ */\r
+DLLIMPORT int GetTzi (TCHAR* zone, TCHAR *result)\r
+{\r
+ DWORD dwStatus, dwType, cbData;\r
+ int cch;\r
+ TCHAR szTime[128], szDate[128], szSubKey[256];\r
+ HKEY hKey;\r
+ REG_TZI_FORMAT tzi;\r
+\r
+ /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms647490%28v=vs.85%29.aspx */\r
+ lstrcpy(szSubKey, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\"));\r
+\r
+ /*\r
+ * https://msdn.microsoft.com/en-us/library/aa272954%28v=vs.60%29.aspx\r
+ * https://msdn.microsoft.com/en-us/library/h1x0y282.aspx\r
+ */\r
+ _tcscat(szSubKey, zone);\r
+\r
+ dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey);\r
+ if (dwStatus != NO_ERROR)\r
+ return GetLastError();\r
+\r
+ cbData = sizeof(REG_TZI_FORMAT);\r
+ dwStatus = RegQueryValueEx (hKey, TEXT("TZI"), NULL, &dwType, (LPBYTE)&tzi, &cbData);\r
+ if (dwStatus != NO_ERROR)\r
+ return GetLastError();\r
+\r
+ /*\r
+ * tzi.StandardDate and tzi.DaylightDate are not a real SYSTEMTIME\r
+ * but we should look at them to depict daylight saving\r
+ * if month = 0 then not supported, year = 0 means every year.\r
+ * http://msdn.microsoft.com/en-us/library/ms725481.asp\r
+ */\r
+\r
+ _stprintf(result, "%d,%d,%d,%d/%d/%d/%d,%d:%d:%d,%d/%d/%d/%d,%d:%d:%d",\r
+ tzi.Bias,tzi.StandardBias,tzi.DaylightBias,\r
+ tzi.StandardDate.wYear,tzi.StandardDate.wMonth,tzi.StandardDate.wDay,tzi.StandardDate.wDayOfWeek,tzi.StandardDate.wHour,tzi.StandardDate.wMinute,tzi.StandardDate.wSecond,\r
+ tzi.DaylightDate.wYear,tzi.DaylightDate.wMonth,tzi.DaylightDate.wDay,tzi.DaylightDate.wDayOfWeek,tzi.DaylightDate.wHour,tzi.DaylightDate.wMinute,tzi.DaylightDate.wSecond\r
+ );\r
+\r
+ return -1;\r
+}\r
+\r
+/*\r
+ * Check for a regex match\r
+ */\r
+DLLIMPORT int RegexpMatch (const char *str, const char *pattern, const char *flags, int errors)\r
+{\r
+ return regexp_match(str, pattern, flags, errors);\r
+}\r
+\r
+/*\r
+ * Return all matches in the regex as a string and return in custom format\r
+ */\r
+DLLIMPORT int RegexpMatches(const char *str, const char *pattern, const char *flags, char *output, int output_len, int errors)\r
+{\r
+ char *matches = regexp_matches(str, pattern, flags, errors);\r
+ int matches_len;\r
+ int result = 0;\r
+\r
+ if (matches != NULL)\r
+ {\r
+ matches_len = strlen(matches);\r
+ if (matches_len <= output_len)\r
+ {\r
+ strncpy(output, matches, matches_len);\r
+ result = 0;\r
+ }\r
+ else\r
+ result = -1;\r
+\r
+ wfree(matches);\r
+ }\r
+ else\r
+ result = -2;\r
+\r
+ return result;\r
+}\r
+\r
+/*\r
+ * Substitutes matches with the regex pattern in the string with the replacement\r
+ * pattern/string.\r
+ */\r
+DLLIMPORT int RegexpReplace(const char *str, const char *pattern, const char *replacement, const char *flags, char *output, int output_len, int errors)\r
+{\r
+ char *replaced = regexp_replace(str, pattern, replacement, flags, errors);\r
+ int replaced_len;\r
+ int result = 0;\r
+\r
+ if (replaced != NULL)\r
+ {\r
+ replaced_len = strlen(replaced);\r
+\r
+ if (replaced_len <= output_len)\r
+ {\r
+ strncpy(output, replaced, replaced_len);\r
+ result = 0;\r
+ }\r
+ else\r
+ result = -1;\r
+\r
+ wfree(replaced);\r
+ }\r
+ else\r
+ result = -2;\r
+\r
+\r
+ return result;\r
+}\r
+\r
+\r
/*\r
* DLL entry point\r
*/\r
* df32func.h\r
* df32func extension definitions\r
*\r
- * Copyright (c) 2007-2009, glyn@8kb.co.uk\r
+ * Copyright (c) 2007-2015, glyn@8kb.co.uk\r
* Author: Glyn Astill <glyn@8kb.co.uk>\r
*\r
*-------------------------------------------------------------------------\r
DLLIMPORT int AcceptClient();\r
DLLIMPORT unsigned int PseudoRand(unsigned int w);\r
DLLIMPORT unsigned int RdtscRand();\r
+DLLIMPORT int GetTzi (TCHAR* zone, TCHAR *result);\r
+DLLIMPORT int RegexpMatch(const char *str, const char *pattern, const char *flags, int errors);\r
+DLLIMPORT int RegexpMatches(const char *str, const char *pattern, const char *flags, char *output, int output_len, int errors);\r
+DLLIMPORT int RegexpReplace(const char *str, const char *pattern, const char *replacement, const char *flags, char *output, int output_len, int errors);\r
\r
#endif /* _DF32FUNC_H_ */\r
//
// This file is to be included when using bigText in df32func.mk
//
-// Copyright (c) 2006-2009, glyn@8kb.co.uk
+// Copyright (c) 2006-2015, glyn@8kb.co.uk
//
// df32func/console.h
//-------------------------------------------------------------------------
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/console.inc\r
//-------------------------------------------------------------------------\r
move 0 to l_iTotalLines\r
move 0 to l_iTotalWidth\r
\r
- direct_input channel default_file_channel argv \r
+ direct_input channel DEFAULT_FILE_CHANNEL argv \r
while not (seqeof)\r
- readln channel default_file_channel l_sBuf\r
+ readln channel DEFAULT_FILE_CHANNEL l_sBuf\r
move (rtrim(l_sBuf)) to l_sbuf\r
move (replaces("{YELLOW}",l_sBuf,"")) to l_sBuf\r
move (replaces("{WHITE}",l_sBuf,"")) to l_sBuf\r
if (length(l_sBuf) > l_iTotalWidth) move ((length(l_sBuf))+1) to l_iTotalWidth\r
increment l_iTotalLines\r
loop\r
- close_input channel default_file_channel \r
+ close_input channel DEFAULT_FILE_CHANNEL \r
\r
while not (key.escape)\r
- direct_input channel default_file_channel argv\r
+ direct_input channel DEFAULT_FILE_CHANNEL argv\r
for l_i from 1 to l_iLineAt\r
- readln channel default_file_channel \r
+ readln channel DEFAULT_FILE_CHANNEL \r
loop\r
for l_i from 1 to 22\r
- readln channel default_file_channel l_sBuf\r
+ readln channel DEFAULT_FILE_CHANNEL l_sBuf\r
gotoxy (l_i-1) 0\r
\r
if (uppercase(l_sBuf) contains "{YELLOW}") begin\r
show (pad(mid(l_sBuf,80,l_iWidthAt),80))\r
screenmode 1\r
loop\r
- close_input channel default_file_channel \r
+ close_input channel DEFAULT_FILE_CHANNEL \r
\r
move "lines " to l_sTmp\r
append l_sTmp (l_iLineAt+1) "-" (l_iLineAt+22) " of " (l_iTotalLines)\r
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/data.inc\r
//-------------------------------------------------------------------------\r
// hash_is_unique - Add a unique constraint on the hash\r
// remove_hash_is_unique - Remove a unique constraint from the hash\r
// matrix_index_lookup_clear - Clear the lookup buffer\r
+// matrix_append_csv - Append some data in CSV format to the array E.g. ('My Name,"My,\"address\""')\r
+// matrix_copy_csv - Copy csv data from sprecified file into matrix\r
//\r
// Set methods:\r
// matrix_value - Set a value at X, Y\r
// matrix_index_lookup_clear - Clear the buffer for an indexed lookup\r
// matrix_index_count_from_value - Get a count of rows with a particular value\r
// matrix_index_from_value - Get the next X pos (row) with indexed value. Returns -1 when nothing left to find.\r
+// item_count - Get count of rows in matrix\r
+// item_width - Get count of columns in matrix\r
// \r
// Example usage:\r
//\r
-//\r
// object test is a matrix\r
// end_object\r
//\r
// set matrix_value of (test(current_object)) item 0 item 1 to "1" - x then y pos to Value\r
// get matrix_value of (test(current_object)) item 0 item 1 to tmpStr - x then y pos to Value\r
+// send matrix_append_csv to test ('My Name,"My,\"address\""') - Append CSV data to the end of the matrix\r
+// send matrix_copy_csv to (test(current_object)) "f:\data.csv" - Copy data from csv file into matrix\r
// send matrix_sort to (test(current_object)) 1 - x then y pos to sort by\r
// send matrix_delete to (test(current_object)) 1 1 - x then y pos to delete \r
// send matrix_delete_row to (test(current_object)) 1 - x essentially blanks record out, no reshuffle\r
-// send delete_item to (test1(current_object)) 1 - x pos (not v efficient), reshuffles\r
+// send delete_item to (test(current_object)) 1 - x pos (not v efficient), reshuffles\r
//\r
// Hash indexed columns usage:\r
//\r
// get matrix_index_from_value of (test(current_object)) item "1" to x_pos \r
// get matrix_indextable_from_value of (test(current_object)) item "1" to tmpStr \r
// get matrix_hash_from_value of (test(current_object)) item "1" to tmpInt \r
+// get item_count of (test(current_object) to tmpInt\r
+// get item_width of (test(current_object) to tmpInt\r
\r
class matrix is an array\r
procedure construct_object integer argc\r
object mTokens is a StringTokenizer\r
end_object\r
- \r
+ object mTokens2 is a StringTokenizer\r
+ end_object\r
+ \r
forward send construct_object\r
property integer c_iWidth public argc\r
property integer c_iHashOn\r
end\r
end_procedure\r
\r
+ procedure matrix_append_csv string row \r
+ local integer l_iMax l_iValues l_i\r
+ local string l_sBuf\r
+ \r
+ forward get item_count to l_iMax\r
+ \r
+ send delete_data to (mTokens2(current_object))\r
+ send set_string_csv to (mTokens2(current_object)) row\r
+ get token_count of (mTokens2(current_object)) to l_iValues\r
+ \r
+ for l_i from 0 to l_iValues \r
+ get token_value of (mTokens2(current_object)) item l_i to l_sBuf\r
+ indicate err false\r
+ set matrix_value item l_iMax item l_i to l_sBuf \r
+ if (err) forward send delete_item l_iMax\r
+ if (err) break\r
+ loop\r
+\r
+ end_procedure\r
+ \r
+ procedure matrix_copy_csv string fname\r
+ local string l_sBuf\r
+ \r
+ if (does_exist(fname)) begin\r
+ direct_input channel DEFAULT_FILE_CHANNEL fname\r
+ while not (seqeof)\r
+ readln channel DEFAULT_FILE_CHANNEL l_sBuf\r
+ if (seqeof) break\r
+ if (trim(l_sBuf) <> "") begin\r
+ send matrix_append_csv l_sBuf\r
+ end\r
+ loop\r
+ close_input channel DEFAULT_FILE_CHANNEL\r
+ end\r
+ else;\r
+ custom_error ERROR_CODE_FILE_NOT_FOUND$ ERROR_MSG_FILE_NOT_FOUND ERROR_DETAIL_FILE_NOT_FOUND fname \r
+ end_procedure \r
+ \r
function matrix_string integer itemx integer itemy returns string\r
local string l_sBuf l_sTmp\r
\r
procedure set item_count integer newVal\r
forward set item_count to newVal\r
end_procedure\r
+ \r
+ function item_width returns integer\r
+ local integer l_iWidth\r
+ get c_iWidth to l_iWidth\r
+ function_return l_iWidth\r
+ end_function\r
\r
procedure matrix_delete integer itemx integer itemy\r
local string l_sBuf l_sTmp l_sOldVal\r
get c_itemCount to l_itemCount\r
get c_ttl to l_iTtl\r
\r
- direct_output channel default_file_channel rssFileName\r
- writeln channel default_file_channel '<?xml version="1.0" ?>'\r
- writeln channel default_file_channel '<?xml-stylesheet type="text/xsl" href="rss.xsl" media="screen"?>'\r
- write channel default_file_channel '<rss version="2.0" xmlns:dc="http:/' '/purl.org/dc/elements/1.1/" xmlns:sy="http:/'\r
- write channel default_file_channel '/purl.org/rss/1.0/modules/syndication/" xmlns:admin="http:/' '/webns.net/mvcb/" xmlns:rdf="http:/'\r
- writeln channel default_file_channel '/www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http:/' '/purl.org/rss/1.0/modules/content/">'\r
+ direct_output channel DEFAULT_FILE_CHANNEL rssFileName\r
+ writeln channel DEFAULT_FILE_CHANNEL '<?xml version="1.0" ?>'\r
+ writeln channel DEFAULT_FILE_CHANNEL '<?xml-stylesheet type="text/xsl" href="rss.xsl" media="screen"?>'\r
+ write channel DEFAULT_FILE_CHANNEL '<rss version="2.0" xmlns:dc="http:/' '/purl.org/dc/elements/1.1/" xmlns:sy="http:/'\r
+ write channel DEFAULT_FILE_CHANNEL '/purl.org/rss/1.0/modules/syndication/" xmlns:admin="http:/' '/webns.net/mvcb/" xmlns:rdf="http:/'\r
+ writeln channel DEFAULT_FILE_CHANNEL '/www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http:/' '/purl.org/rss/1.0/modules/content/">'\r
\r
// skipHours skipDays cloud - all currently not used\r
// Write out Channel\r
- writeln channel default_file_channel ' <channel>'\r
- writeln channel default_file_channel ' <title>' (trim(l_rssTitle)) '</title>'\r
- writeln channel default_file_channel ' <link>' (trim(l_rssLink)) '</link>'\r
- writeln channel default_file_channel ' <description>' (trim(l_rssDesc)) '</description>'\r
- writeln channel default_file_channel ' <language>en-gb</language>'\r
- writeln channel default_file_channel ' <generator>Df32func RSS Object Generator</generator>'\r
- writeln channel default_file_channel ' <copyright>Copyright ' (trim(l_rssTitle)) ' (C) ' (now("date")) '</copyright>'\r
- writeln channel default_file_channel ' <lastBuildDate>' (rssdate((now("date")),(now("longtime")))) '</lastBuildDate>'\r
- writeln channel default_file_channel ' <pubDate>' (rssdate((now("date")),(now("longtime")))) '</pubDate>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <channel>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <title>' (trim(l_rssTitle)) '</title>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <link>' (trim(l_rssLink)) '</link>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <description>' (trim(l_rssDesc)) '</description>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <language>en-gb</language>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <generator>Df32func RSS Object Generator</generator>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <copyright>Copyright ' (trim(l_rssTitle)) ' (C) ' (now("date")) '</copyright>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <lastBuildDate>' (rssdate((now("date")),(now("longtime")))) '</lastBuildDate>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <pubDate>' (rssdate((now("date")),(now("longtime")))) '</pubDate>'\r
\r
- if (l_manEditor <> "") writeln channel default_file_channel ' <managingEditor>' l_manEditor '</managingEditor>'\r
- if (l_webMaster <> "") writeln channel default_file_channel ' <webMaster>' l_webMaster '</webMaster>'\r
- if (l_iTtl <> 0) writeln channel default_file_channel ' <ttl>' l_iTtl '</ttl>' \r
+ if (l_manEditor <> "") writeln channel DEFAULT_FILE_CHANNEL ' <managingEditor>' l_manEditor '</managingEditor>'\r
+ if (l_webMaster <> "") writeln channel DEFAULT_FILE_CHANNEL ' <webMaster>' l_webMaster '</webMaster>'\r
+ if (l_iTtl <> 0) writeln channel DEFAULT_FILE_CHANNEL ' <ttl>' l_iTtl '</ttl>' \r
\r
// Write out image\r
if ((l_imgUrl <> "") and (l_imgx > 0) and (l_imgy > 0)) begin\r
- writeln channel default_file_channel ' <image>'\r
- writeln channel default_file_channel ' <title>' (trim(l_imgTitle)) '</title>'\r
- writeln channel default_file_channel ' <url>' (trim(l_imgUrl)) '</url>'\r
- writeln channel default_file_channel ' <link>' (trim(l_imgLink)) '</link>'\r
- writeln channel default_file_channel ' <height>' l_imgx '</height>'\r
- writeln channel default_file_channel ' <width>' l_imgy '</width>'\r
- writeln channel default_file_channel ' <description>' (trim(l_rssDesc)) '</description>'\r
- writeln channel default_file_channel ' </image>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <image>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <title>' (trim(l_imgTitle)) '</title>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <url>' (trim(l_imgUrl)) '</url>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <link>' (trim(l_imgLink)) '</link>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <height>' l_imgx '</height>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <width>' l_imgy '</width>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <description>' (trim(l_rssDesc)) '</description>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' </image>'\r
end\r
\r
// Write out items\r
move (replaces('<',l_itemDesc,"<")) to l_itemDesc\r
move (replaces('>',l_itemDesc,">")) to l_itemDesc\r
\r
- writeln channel default_file_channel ' <item>'\r
- writeln channel default_file_channel ' <title>' l_itemTitle '</title>'\r
- writeln channel default_file_channel ' <link>' l_itemLink '</link>'\r
- writeln channel default_file_channel ' <description>' l_itemDesc '</description>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <item>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <title>' l_itemTitle '</title>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <link>' l_itemLink '</link>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <description>' l_itemDesc '</description>'\r
\r
if (l_itemGuID = "") begin\r
move 0 to l_iConflict\r
end\r
if (l_itemGuID <> "") append l_itemLink "#" l_itemGuID\r
\r
- writeln channel default_file_channel ' <guid isPermaLink="false">' l_itemLink '</guid>'\r
- if ((l_pubDate = "") or (l_pubDate = "NOW")) writeln channel default_file_channel ' <pubDate>' (rssdate((now("date")),(now("longtime")))) '</pubDate>'\r
- else writeln channel default_file_channel ' <pubDate>' l_pubDate '</pubDate>'\r
- writeln channel default_file_channel ' <category>' l_itemCat '</category>'\r
- writeln channel default_file_channel ' </item>' \r
+ writeln channel DEFAULT_FILE_CHANNEL ' <guid isPermaLink="false">' l_itemLink '</guid>'\r
+ if ((l_pubDate = "") or (l_pubDate = "NOW")) writeln channel DEFAULT_FILE_CHANNEL ' <pubDate>' (rssdate((now("date")),(now("longtime")))) '</pubDate>'\r
+ else writeln channel DEFAULT_FILE_CHANNEL ' <pubDate>' l_pubDate '</pubDate>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' <category>' l_itemCat '</category>'\r
+ writeln channel DEFAULT_FILE_CHANNEL ' </item>' \r
loop\r
\r
// Write out file/channel close\r
- writeln channel default_file_channel ' </channel>'\r
- writeln channel default_file_channel '</rss>' \r
- close_output channel default_file_channel\r
+ writeln channel DEFAULT_FILE_CHANNEL ' </channel>'\r
+ writeln channel DEFAULT_FILE_CHANNEL '</rss>' \r
+ close_output channel DEFAULT_FILE_CHANNEL\r
\r
end_procedure \r
\r
set c_filelistDirectory to filelistDirectory\r
set c_filelistName to filelistName\r
\r
- direct_input channel default_file_channel (filelistDirectory+filelistName)\r
+ direct_input channel DEFAULT_FILE_CHANNEL (filelistDirectory+filelistName)\r
read_block l_sHead 256 \r
while not (seqeof) \r
//Block of 128 split 41\33\54\r
- read_block channel default_file_channel l_sRootName 41\r
- read_block channel default_file_channel l_sUserDisplayName 33\r
- read_block channel default_file_channel l_sFileName 54\r
+ read_block channel DEFAULT_FILE_CHANNEL l_sRootName 41\r
+ read_block channel DEFAULT_FILE_CHANNEL l_sUserDisplayName 33\r
+ read_block channel DEFAULT_FILE_CHANNEL l_sFileName 54\r
\r
move filelistDirectory to l_sUrn\r
append l_sUrn (trim(cstring(l_sFileName))) ".FD"\r
increment l_iFileNumber\r
end\r
loop \r
- close_input channel default_file_channel\r
+ close_input channel DEFAULT_FILE_CHANNEL\r
\r
set c_itemCount to l_iFileNumber\r
end_procedure\r
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/date.inc\r
//-------------------------------------------------------------------------\r
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/depmacro.inc\r
//-------------------------------------------------------------------------\r
-df32func.inc last compiled on 09/04/2009 at 21:45:13.05 \r
+df32func.inc last compiled on 25/09/2015 at 14:46:00.74 \r
df32func DLL functions: \r
-tcpcomm.h:external_function ClientSocket "ClientSocket" df32func.dll dword port string host returns integer\r
-tcpcomm.h:external_function ServerSocket "ServerSocket" df32func.dll dword port returns integer\r
-tcpcomm.h:external_function AcceptClient "AcceptClient" df32func.dll returns integer\r
-tcpcomm.h:external_function Send "Send" df32func.dll dword socket string data returns integer\r
-tcpcomm.h:external_function Receive "Receive" df32func.dll dword socket pointer dataOut returns integer\r
-tcpcomm.h:external_function CloseConnection "CloseConnection" df32func.dll dword socket returns integer\r
-tcpcomm.h:external_function PseudoRand "PseudoRand" df32func.dll dword w returns integer\r
-tcpcomm.h:external_function RdtscRand "RdtscRand" df32func.dll returns integer\r
-win32.h:external_function GetDateFormat "GetDateFormatA" kernel32.dll dword LCID dword dwFlags pointer lpsSystemTime pointer lpFormat pointer lpDateStr integer cchDate returns integer\r
+df32func.h:external_function ClientSocket "ClientSocket" df32func.dll dword port string host returns integer\r
+df32func.h:external_function ServerSocket "ServerSocket" df32func.dll dword port returns integer\r
+df32func.h:external_function AcceptClient "AcceptClient" df32func.dll returns integer\r
+df32func.h:external_function Send "Send" df32func.dll dword socket string data returns integer\r
+df32func.h:external_function Receive "Receive" df32func.dll dword socket pointer dataOut returns integer\r
+df32func.h:external_function CloseConnection "CloseConnection" df32func.dll dword socket returns integer\r
+df32func.h:external_function PseudoRand "PseudoRand" df32func.dll dword w returns integer\r
+df32func.h:external_function RdtscRand "RdtscRand" df32func.dll returns integer\r
+df32func.h:external_function GetTzi "GetTzi" df32func.dll pointer lpTimeZone pointer lpResult returns integer\r
+df32func.h:external_function RegexpMatch "RegexpMatch" df32func.dll pointer str pointer pattern pointer flags integer errors returns integer\r
+df32func.h:external_function RegexpMatches "RegexpMatches" df32func.dll pointer str pointer pattern pointer flags pointer out pointer out_len integer errors returns integer\r
+df32func.h:external_function RegexpReplace "RegexpReplace" df32func.dll pointer str pointer pattern pointer replacement pointer flags pointer out pointer out_len integer errors returns integerwin32.h:external_function GetDateFormat "GetDateFormatA" kernel32.dll dword LCID dword dwFlags pointer lpsSystemTime pointer lpFormat pointer lpDateStr integer cchDate returns integer\r
win32.h:external_function GetTimeFormat "GetTimeFormatA" kernel32.dll dword LCID dword dwFlags pointer lpsSystemTime pointer lpFormat pointer lpTimeStr integer cchTime returns integer\r
win32.h:external_function GetFileTime "GetFileTime" kernel32.dll handle hFileHandle pointer lpCreationTime pointer lpLastAccessTime pointer lpLastWriteTime returns integer\r
win32.h:external_function FileTimeToSystemTime "FileTimeToSystemTime" kernel32.dll pointer lpFileTime Pointer lpSystemTime returns integer\r
win32.h:external_function EnumProcesses "EnumProcesses" psapi.dll pointer lpidProcess integer cb pointer cbNeeded returns integer\r
win32.h:external_function EnumProcessModules "EnumProcessModules" psapi.dll handle hProcess pointer lphModule integer cb integer cbNeeded returns integer\r
win32.h:external_function WideCharToMultiByte "WideCharToMultiByte" kernel32.dll integer cp dword dwF pointer lpWCS integer cchWC pointer lpMBS integer cchMB string dC string uDC returns integer\r
+win32.h:external_function CharToOem "CharToOemA" user32.dll pointer lpszSrc pointer lpszDst returns integer\r
+win32.h:external_function OemToChar "OemToCharA" user32.dll pointer lpszSrc pointer lpszDst returns integer\r
win32.h:external_function GetSystemTime "GetSystemTime" kernel32.dll Pointer lpGST returns VOID_TYPE\r
win32.h:external_function GetTickCount "GetTickCount" kernel32.dll returns dWord\r
win32.h:external_function32 CoCreateGuid "CoCreateGuid" ole32.dll pointer pGUIDStructure returns word\r
win32.h:external_function GetVersionEx "GetVersionExA" kernel32.dll pointer lpVersionInfo returns integer\r
win32.h:external_function GetSystemTime "GetSystemTime" kernel32.dll pointer lpSystemTime returns integer\r
win32.h:external_function GetTimeZoneInformation "GetTimeZoneInformation" kernel32.dll pointer lpTimeZoneInformation returns integer\r
-win32.h:external_function GetTzi "GetTzi" timezone.dll pointer lpTimeZone pointer lpResult returns integer\r
df32func functions: \r
console.inc:function set_mode global integer argv returns integer\r
console.inc:function screen_display global string argv returns integer\r
math.inc:function rshift global integer argv integer shift_by returns integer\r
math.inc:function lshift global integer argv integer shift_by returns integer\r
math.inc:function ternary global string argv string argv2 string argv3 returns string\r
+regex.inc:function regexp_match global string str string pattern string flags returns integer\r
+regex.inc:function regexp_matches global string str string pattern string flags returns string\r
+regex.inc:function regexp_replace global string str string pattern string replacement string flags returns string\r
+regex.inc:function regexp_matches_count global string argv returns integer\r
+regex.inc:function regexp_matches_item global string argv integer argv2 returns string\r
string.inc:function titlecase global string argv returns string\r
string.inc:function replaceall global string argv string argv2 string argv3 returns string\r
string.inc:function zeropad global string argv integer argv2 returns string\r
win32.inc:function to_ascii global string argv returns string\r
win32.inc:function to_unicode global string argv returns string\r
win32.inc:function to_utf8 global string argv returns string\r
+win32.inc:function ansi_to_oem global string argv returns string\r
+win32.inc:function oem_to_ansi global string argv returns string\r
win32.inc:function get_procs global integer argv returns integer\r
win32.inc:function time_data global integer argv returns string\r
win32.inc:function fill_0 global integer iValue integer iSize returns string\r
data.inc:class ListDirectory is a matrix\r
data.inc:class ProcessList is an array\r
string.inc:class StringTokenizer is an array\r
+tap.inc:class TAP is an array
+tap.inc:class TAP_harness is a TAP
win32.inc:class msAdvCrypt is an array\r
//\r
// This is the file to be compiled by the dfcomp command\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/df32func.mk\r
//-------------------------------------------------------------------------\r
// Set dataflex epoch and set date format to 4 digit years\r
//-------------------------------------------------------------------------\r
\r
-set_date_attribute date4_state to dftrue\r
-set_date_attribute epoch_value to 80\r
-set_date_attribute sysdate4_state to dftrue\r
+set_date_attribute date4_state to dftrue\r
+set_date_attribute epoch_value to 80\r
+set_date_attribute sysdate4_state to dftrue\r
\r
//-------------------------------------------------------------------------\r
// Standard DF32 Console Mode packages \r
// Defines used to control some compile time behaviour\r
//-------------------------------------------------------------------------\r
\r
-//Define enable_dfassert\r
-Define no_backslash_quote\r
-Define default_file_channel for 9\r
+//Define ENABLE_DFASSERT\r
+\r
+Define NO_BACKSLASH_QUOTE\r
+\r
+#IFDEF DEFAULT_FILE_CHANNEL\r
+#ELSE\r
+ Define DEFAULT_FILE_CHANNEL for 9\r
+#ENDIF\r
+\r
+#IFDEF MAX_DFREGEX_BUFFER\r
+#ELSE\r
+ Define MAX_DFREGEX_BUFFER for 16384\r
+#ENDIF\r
+\r
+#IFDEF ERRORS_TO_STDERR\r
+#ELSE\r
+ Define ERRORS_TO_STDERR for 0\r
+#ENDIF\r
+\r
\r
//-------------------------------------------------------------------------\r
// Global variables used to control some runtime behaviour\r
\r
//Including header file win32.h\r
#INCLUDE win32.h\r
-//Including include file tcpcom.h\r
-#INCLUDE tcpcomm.h\r
+//Including include file df32func.h\r
+#INCLUDE df32func.h\r
//Including include file console.h\r
#INCLUDE console.h\r
//Including include file encode.h\r
#INCLUDE macro.inc\r
//Including include file math.inc\r
#INCLUDE math.inc\r
+//Including include file tap.inc\r
+#INCLUDE tap.inc\r
+//Including include file regex.inc\r
+#INCLUDE regex.inc\r
//Including include file win32.inc\r
#INCLUDE win32.inc\r
//Including include file string.inc\r
//
// This file is to be included when using RC4/Base64 encoding in df32func.mk
//
-// Copyright (c) 2006-2009, glyn@8kb.co.uk
+// Copyright (c) 2006-2015, glyn@8kb.co.uk
//
// df32func/encode.h
//-------------------------------------------------------------------------
//
// This file is to be included in df32func.mk
//
-// Copyright (c) 2006-2009, glyn@8kb.co.uk
-//
+// Copyright (c) 2006-2015, glyn@8kb.co.uk
+//
// df32func/errors.h
//-------------------------------------------------------------------------
Define ERROR_CODE_INVALID_TIMESTAMP$
Define ERROR_CODE_INVALID_POSIX_NUMBER$
Define ERROR_CODE_INVALID_SYSTEM_TIMEZONE$
+ Define ERROR_CODE_COMPARISON_OPERATOR$
Define ERROR_CODE_INVALID_BOOLEAN$
+ Define ERROR_CODE_REGEX_BUFFER_OVERFLOW$
+ Define ERROR_CODE_REGEX_COMPILE_FAILURE$
+ Define ERROR_CODE_FILE_NOT_FOUND$
end_enum_list
//-------------------------------------------------------------------------
#REPLACE ERROR_MSG_INVALID_POSIX_NUMBER "Invalid posix number: ??"
#REPLACE ERROR_MSG_INVALID_SYSTEM_TIMEZONE "Invalid system timezone"
#REPLACE ERROR_MSG_INVALID_BOOLEAN "Value does not evaluate to boolean"
+#REPLACE ERROR_MSG_COMPARISON_OPERATOR "Not a valid operator: ??"
+#REPLACE ERROR_MSG_REGEX_BUFFER_OVERFLOW "Regex output buffer too small: ??"
+#REPLACE ERROR_MSG_REGEX_COMPILE_FAILURE "Regex compilation failed"
+#REPLACE ERROR_MSG_FILE_NOT_FOUND "File not found or permission denied"
//-------------------------------------------------------------------------
// Error message detail
#REPLACE ERROR_DETAIL_GETLASTERROR "GetLastError = ??"
#REPLACE ERROR_DETAIL_INVALID_TIMESTAMP "Format: ??"
#REPLACE ERROR_DETAIL_INVALID_BOOLEAN "Value ?? != true/false"
+#REPLACE ERROR_DETAIL_FILE_NOT_FOUND "File: ??"
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/hash.inc\r
//-------------------------------------------------------------------------\r
//
// This file is to be included in df32func.mk
//
-// Copyright (c) 2006-2009, glyn@8kb.co.uk
+// Copyright (c) 2006-2015, glyn@8kb.co.uk
//
// df32func/macro.inc
//-------------------------------------------------------------------------
// ASSERT (1=2) "TEST ASSERT"
//
#COMMAND ASSERT R
- #IFDEF enable_dfassert
+ #IFDEF ENABLE_DFASSERT
#IF (!0=2)
#IFTYPE !1 "I"
if (!1 = 0);
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/math.inc\r
//-------------------------------------------------------------------------\r
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/string.inc\r
//-------------------------------------------------------------------------\r
\r
// Standard escaping via C standard.\r
//\r
-// For PostgreSQL when no_backslash_quote is defined single quotes are \r
+// For PostgreSQL when NO_BACKSLASH_QUOTE is defined single quotes are \r
// escaped per SQL standard by doubling '' rather than \' because in \r
// some encodings multibyte characters have a last byte numerically \r
// equivalent to ASCII escaped by backslash "\".\r
local string l_sReturn\r
\r
move (replaces("\",argv,"\\")) to l_sReturn\r
- #IFDEF no_backslash_quote\r
+ #IFDEF NO_BACKSLASH_QUOTE\r
move (replaces("'",l_sReturn,"''")) to l_sReturn\r
#ELSE\r
move (replaces("'",l_sReturn,"\'")) to l_sReturn\r
\r
if (outfile = "") begin\r
move (file_size_bytes(l_sFile)) to l_iFileSize\r
- direct_input channel default_file_channel l_sFile\r
- read_block channel default_file_channel l_sReturn l_iFileSize\r
- close_input channel default_file_channel\r
+ direct_input channel DEFAULT_FILE_CHANNEL l_sFile\r
+ read_block channel DEFAULT_FILE_CHANNEL l_sReturn l_iFileSize\r
+ close_input channel DEFAULT_FILE_CHANNEL\r
move (fileopp("delete",l_sFile,"")) to l_iThrow\r
end\r
else move outfile to l_sReturn\r
// String tokenizer class\r
//\r
// Send message methods:\r
-// set_string\r
-//\r
+// set_string <string> <delimiter> - Send the string to be tokenized and the delimiter to split on\r
+// set_string_csv <string> - Send a CSV string to be tokenized. As per general CSV data:\r
+// * Items containting commas to be enclosed in double quotes: '"'\r
+// * Double quotes in quotes to be escaped with a backslash: '\'\r
+// \r
// Set methods:\r
// token_value \r
//\r
set c_iTokenOn to 0\r
set c_iTokens to l_iTokens\r
end_procedure\r
+ \r
+ procedure set_string_csv string argv \r
+ local integer l_i l_iQuot l_iTokens\r
+ local string l_sChar l_sLast l_sNext l_sBuf\r
+ \r
+ move -1 to l_iTokens\r
+ move 0 to l_iQuot\r
+ move "" to l_sLast\r
+ \r
+ for l_i from 0 to (length(argv))\r
+ move (mid(argv,1,l_i)) to l_sChar\r
+ move (mid(argv,1,l_i+1)) to l_sNext\r
+ move (mid(argv,1,l_i-1)) to l_sLast \r
+ \r
+ if ((l_iQuot) and (l_sChar = '\') and (l_sNext = '"')) break begin\r
+ \r
+ if ((l_sChar = '"') and (l_sLast <> '\')) begin\r
+ if (l_iQuot) move 0 to l_iQuot\r
+ else move 1 to l_iQuot\r
+ end\r
+ if ((l_sChar = '"') and (l_sLast <> '\')) break begin \r
+ \r
+ if ((l_sChar = ',') and not (l_iQuot)) begin\r
+ //fwd to Array\r
+ increment l_iTokens\r
+ forward set array_value item l_iTokens to l_sBuf\r
+ move "" to l_sBuf\r
+ end\r
+ if ((l_sChar = ',') and not (l_iQuot)) break begin\r
+ \r
+ append l_sBuf l_sChar\r
+ loop\r
+ \r
+ //fwd to Array\r
+ increment l_iTokens \r
+ forward set array_value item l_iTokens to l_sBuf\r
+\r
+ set c_iTokenOn to 0 \r
+ set c_iTokens to l_iTokens\r
+ end_procedure \r
\r
procedure set token_value integer itemx string val\r
forward set array_value item itemx to val\r
//\r
// This file is to be included in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/tstamp.inc\r
//-------------------------------------------------------------------------\r
//\r
// This file is to be included when using Win32 capabilities in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/win32.h\r
//-------------------------------------------------------------------------\r
external_function EnumProcesses "EnumProcesses" psapi.dll pointer lpidProcess integer cb pointer cbNeeded returns integer\r
external_function EnumProcessModules "EnumProcessModules" psapi.dll handle hProcess pointer lphModule integer cb integer cbNeeded returns integer\r
external_function WideCharToMultiByte "WideCharToMultiByte" kernel32.dll integer cp dword dwF pointer lpWCS integer cchWC pointer lpMBS integer cchMB string dC string uDC returns integer\r
+external_function CharToOem "CharToOemA" user32.dll pointer lpszSrc pointer lpszDst returns integer\r
+external_function OemToChar "OemToCharA" user32.dll pointer lpszSrc pointer lpszDst returns integer\r
external_function GetSystemTime "GetSystemTime" kernel32.dll Pointer lpGST returns VOID_TYPE\r
external_function GetTickCount "GetTickCount" kernel32.dll returns dWord\r
external_function32 CoCreateGuid "CoCreateGuid" ole32.dll pointer pGUIDStructure returns word\r
external_function GetVersionEx "GetVersionExA" kernel32.dll pointer lpVersionInfo returns integer\r
external_function GetSystemTime "GetSystemTime" kernel32.dll pointer lpSystemTime returns integer\r
external_function GetTimeZoneInformation "GetTimeZoneInformation" kernel32.dll pointer lpTimeZoneInformation returns integer\r
-external_function GetTzi "GetTzi" timezone.dll pointer lpTimeZone pointer lpResult returns integer\r
\r
//-------------------------------------------------------------------------\r
// Constants\r
//\r
// This file is to be included when using Win32 capabilities in df32func.mk\r
//\r
-// Copyright (c) 2006-2009, glyn@8kb.co.uk\r
+// Copyright (c) 2006-2015, glyn@8kb.co.uk\r
// \r
// df32func/win32.inc\r
//-------------------------------------------------------------------------\r
move (trim(argv)) to l_sUnicode\r
\r
if (l_sUnicode <> "") begin\r
- zerostring 100 to l_sAscii\r
+ zerostring (length(l_sUnicode)) to l_sAscii\r
getAddress of l_sAscii to l_pAscii\r
getAddress of l_sUnicode to l_pUnicode\r
\r
- // set the length of cchWideChar to -1 and function assumes null termination and calculates lenght itsself\r
+ // set the length of cchWideChar to -1 and function assumes null termination and calculates length itsself\r
move (WideCharToMultiByte(CP_OEMCP,0,l_pUnicode,-1,0,0,0,0)) to l_iCharsNeeded \r
move (WideCharToMultiByte(CP_OEMCP,0,l_pUnicode,-1,l_pAscii,l_iCharsNeeded,0,0)) to l_iThrow\r
end\r
- function_return l_sAscii\r
+ function_return (cstring(l_sAscii))\r
end_function\r
\r
// Attempt to convert a string from ASCII to unicode via MultiByteToWideChar\r
move (trim(argv)) to l_sAscii\r
\r
if (l_sAscii <> "") begin\r
- zerostring 100 to l_sUnicode\r
+ zerostring (length(l_sAscii)*2) to l_sUnicode\r
getAddress of l_sUnicode to l_pUnicode\r
getAddress of l_sAscii to l_pAscii\r
\r
- // set the length of cchWideChar to -1 and function assumes null termination and calculates lenght itsself\r
+ // set the length of cchWideChar to -1 and function assumes null termination and calculates length itsself\r
move (MultiByteToWideChar(CP_ACP,0,l_pAscii,-1,0,0,0,0)) to l_iCharsNeeded \r
move (MultiByteToWideChar(CP_ACP,0,l_pAscii,-1,l_pUnicode,l_iCharsNeeded,0,0)) to l_iThrow\r
end\r
- function_return l_sUnicode \r
+ function_return (cstring(l_sUnicode)) \r
end_function\r
\r
// Attempt to convert a string from ascii to UTF8 via WideCharToMultiByte\r
move (trim(argv)) to l_sUnicode\r
\r
if (l_sUnicode <> "") begin\r
- zerostring 100 to l_sUTF8\r
+ zerostring (length(l_sUnicode)) to l_sUTF8\r
getAddress of l_sUTF8 to l_pUTF8\r
getAddress of l_sUnicode to l_pUnicode\r
\r
move (WideCharToMultiByte(CP_UTF8,0,l_pUTF8,-1,l_pUnicode,l_iCharsNeeded,0,0)) to l_iThrow\r
end\r
\r
- function_return l_sUTF8\r
+ function_return (cstring(l_sUTF8))\r
+end_function\r
+\r
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647473%28v=vs.85%29.aspx\r
+// Note security considerations, as this function doesn't enforce string lengths\r
+function ansi_to_oem global string argv returns string\r
+ local string l_sOem l_sAnsi\r
+ local pointer l_pOem l_pAnsi\r
+ local integer l_iResult\r
+ \r
+ if (length(argv) <> 0) begin\r
+ move argv to l_sAnsi\r
+ getaddress of l_sAnsi to l_pAnsi\r
+ zerostring (length(l_sAnsi)+1) to l_sOem\r
+ getaddress of l_sOem to l_pOem\r
+ move (CharToOem(l_pAnsi, l_pOem)) to l_iResult\r
+ end\r
+ else;\r
+ move argv to l_sOem\r
+ \r
+ function_return (cstring(l_sOem))\r
+end_function\r
+\r
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647493%28v=vs.85%29.aspx\r
+// Note security considerations, as this function doesn't enforce string lengths\r
+function oem_to_ansi global string argv returns string\r
+ local string l_sOem l_sAnsi\r
+ local pointer l_pOem l_pAnsi\r
+ local integer l_iResult\r
+ \r
+ if (length(argv) <> 0) begin\r
+ move argv to l_sOem\r
+ getaddress of l_sOem to l_pOem\r
+ zerostring (length(l_sOem)+1) to l_sAnsi\r
+ getaddress of l_sAnsi to l_pAnsi\r
+ move (CharToOem(l_pOem, l_pAnsi)) to l_iResult\r
+ end\r
+ else;\r
+ move argv to l_sAnsi\r
+ \r
+ function_return (cstring(l_sAnsi))\r
end_function\r
\r
// Get running processes on the system\r