...
 
Commits (18)
extraction:
cpp:
prepare:
packages:
- python3-cffi
......@@ -2,7 +2,7 @@ sudo: required
services: docker
before_install:
- docker pull ubuntu:16.04
- docker run --privileged --cidfile=/tmp/cid ubuntu:16.04 /bin/sh -c 'apt-get update && apt-get install -y meson/xenial-backports libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk2.0-dev libluajit-5.1-dev libnotify-dev libpci-dev libperl-dev libproxy-dev libssl-dev python3-dev mono-devel desktop-file-utils'
- docker run --privileged --cidfile=/tmp/cid ubuntu:16.04 /bin/sh -c 'apt-get update && apt-get install -y meson/xenial-backports libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk2.0-dev libluajit-5.1-dev libnotify-dev libpci-dev libperl-dev libproxy-dev libssl-dev python3-dev python3-cffi mono-devel desktop-file-utils'
- docker commit `cat /tmp/cid` hexchat/ubuntu-ci
- rm -f /tmp/cid
install:
......
......@@ -49,6 +49,10 @@ config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_34')
config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr'))
config_h.set('HAVE_STRINGS_H', cc.has_header('strings.h'))
config_h.set_quoted('HEXCHATLIBDIR',
join_paths(get_option('prefix'), get_option('libdir'), 'hexchat/plugins')
)
if libssl_dep.found()
config_h.set('HAVE_X509_GET_SIGNATURE_NID',
cc.has_function('X509_get_signature_nid', dependencies: libssl_dep)
......
This diff is collapsed.
#!/usr/bin/env python3
import sys
import cffi
builder = cffi.FFI()
# hexchat-plugin.h
with open(sys.argv[1]) as f:
output = []
eat_until_endif = 0
# This is very specific to hexchat-plugin.h, it is not a cpp
for line in f:
if line.startswith('#define'):
continue
elif line.endswith('HEXCHAT_PLUGIN_H\n'):
continue
elif 'time.h' in line:
output.append('typedef int... time_t;')
elif line.startswith('#if'):
eat_until_endif += 1
elif line.startswith('#endif'):
eat_until_endif -= 1
elif eat_until_endif and '_hexchat_context' not in line:
continue
else:
output.append(line)
builder.cdef(''.join(output))
builder.embedding_api('''
extern "Python" int _on_py_command(char **, char **, void *);
extern "Python" int _on_load_command(char **, char **, void *);
extern "Python" int _on_unload_command(char **, char **, void *);
extern "Python" int _on_reload_command(char **, char **, void *);
extern "Python" int _on_say_command(char **, char **, void *);
extern "Python" int _on_command_hook(char **, char **, void *);
extern "Python" int _on_print_hook(char **, void *);
extern "Python" int _on_print_attrs_hook(char **, hexchat_event_attrs *, void *);
extern "Python" int _on_server_hook(char **, char **, void *);
extern "Python" int _on_server_attrs_hook(char **, char **, hexchat_event_attrs *, void *);
extern "Python" int _on_timer_hook(void *);
extern "Python" int _on_plugin_init(char **, char **, char **, char *, char *);
extern "Python" int _on_plugin_deinit(void);
static hexchat_plugin *ph;
''')
builder.set_source('_hexchat_embedded', '''
/* Python's header defines these.. */
#undef HAVE_MEMRCHR
#undef HAVE_STRINGS_H
#include "config.h"
#include "hexchat-plugin.h"
static hexchat_plugin *ph;
CFFI_DLLEXPORT int _on_plugin_init(char **, char **, char **, char *, char *);
CFFI_DLLEXPORT int _on_plugin_deinit(void);
int hexchat_plugin_init(hexchat_plugin *plugin_handle,
char **name_out, char **description_out,
char **version_out, char *arg)
{
if (ph != NULL)
{
puts ("Python plugin already loaded\\n");
return 0; /* Prevent loading twice */
}
ph = plugin_handle;
return _on_plugin_init(name_out, description_out, version_out, arg, HEXCHATLIBDIR);
}
int hexchat_plugin_deinit(void)
{
int ret = _on_plugin_deinit();
ph = NULL;
return ret;
}
''')
# python.py
with open(sys.argv[2]) as f:
builder.embedding_init_code(f.read())
# python.c
builder.emit_c_code(sys.argv[3])
from _hexchat import *
......@@ -5,8 +5,18 @@ else
python_dep = dependency(python_opt, version: '>= 2.7')
endif
shared_module('python', 'python.c',
dependencies: [libgio_dep, hexchat_plugin_dep, python_dep],
python3_source = custom_target('python-bindings',
input: ['../../src/common/hexchat-plugin.h', 'python.py'],
output: 'python.c',
command: [find_program('generate_plugin.py'), '@INPUT@', '@OUTPUT@']
)
install_data(['_hexchat.py', 'hexchat.py', 'xchat.py'],
install_dir: join_paths(get_option('libdir'), 'hexchat/python')
)
shared_module('python', python3_source,
dependencies: [hexchat_plugin_dep, python_dep],
install: true,
install_dir: plugindir,
name_prefix: '',
......
This diff is collapsed.
EXPORTS
hexchat_plugin_init
hexchat_plugin_deinit
hexchat_plugin_get_info
This diff is collapsed.
......@@ -37,6 +37,9 @@
<AdditionalDependencies>"$(Python2Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\hexchat-plugin.h python.py "$(IntDir)python.c"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
......@@ -48,12 +51,15 @@
<AdditionalDependencies>"$(Python2Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\hexchat-plugin.h python.py "$(IntDir)python.c"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="python.def" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="python.c" />
<ClCompile Include="$(IntDir)python.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
......@@ -37,6 +37,9 @@
<AdditionalDependencies>"$(Python3Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\hexchat-plugin.h python.py "$(IntDir)python.c"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
......@@ -48,12 +51,20 @@
<AdditionalDependencies>"$(Python3Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>"$(Python3Path)\python.exe" generate_plugin.py ..\..\src\common\hexchat-plugin.h python.py "$(IntDir)python.c"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="generate_plugin.py" />
<None Include="hexchat.py" />
<None Include="python.def" />
<None Include="python.py" />
<None Include="xchat.py" />
<None Include="_hexchat.py" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="python.c" />
<ClCompile Include="$(IntDir)python.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>
\ No newline at end of file
......@@ -9,13 +9,26 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="python.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)python.c" />
</ItemGroup>
<ItemGroup>
<None Include="python.def">
<Filter>Resource Files</Filter>
</None>
<None Include="_hexchat.py">
<Filter>Source Files</Filter>
</None>
<None Include="generate_plugin.py">
<Filter>Source Files</Filter>
</None>
<None Include="hexchat.py">
<Filter>Source Files</Filter>
</None>
<None Include="python.py">
<Filter>Source Files</Filter>
</None>
<None Include="xchat.py">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>
\ No newline at end of file
# HexChat Python Module Style Guide
(This is a work in progress).
## General rules
- PEP8 as general fallback recommendations
- Max line length: 120
- Avoid overcomplex compound statements. i.e. dont do this: `somevar = x if x == y else z if a == b and c == b else x`
## Indentation style
### Multi-line functions
```python
foo(really_long_arg_1,
really_long_arg_2)
```
### Mutli-line lists/dicts
```python
foo = {
'bar': 'baz',
}
```
from _hexchat import *
......@@ -1618,13 +1618,13 @@ dcc_accept (GIOChannel *source, GIOCondition condition, struct DCC *dcc)
}
guint32
dcc_get_my_address (void) /* the address we'll tell the other person */
dcc_get_my_address (session *sess) /* the address we'll tell the other person */
{
struct hostent *dns_query;
guint32 addr = 0;
if (prefs.hex_dcc_ip_from_server && prefs.dcc_ip)
addr = prefs.dcc_ip;
if (prefs.hex_dcc_ip_from_server && sess->server->dcc_ip)
addr = sess->server->dcc_ip;
else if (prefs.hex_dcc_ip[0])
{
dns_query = gethostbyname ((const char *) prefs.hex_dcc_ip);
......@@ -1710,7 +1710,7 @@ dcc_listen_init (struct DCC *dcc, session *sess)
/*if we have a dcc_ip, we use that, so the remote client can connect*/
/*else we try to take an address from hex_dcc_ip*/
/*if something goes wrong we tell the client to connect to our LAN ip*/
dcc->addr = dcc_get_my_address ();
dcc->addr = dcc_get_my_address (sess);
/*if nothing else worked we use the address we bound to*/
if (dcc->addr == 0)
......
......@@ -124,7 +124,7 @@ void dcc_chat (session *sess, char *nick, int passive);
void handle_dcc (session *sess, char *nick, char *word[], char *word_eol[],
const message_tags_data *tags_data);
void dcc_show_list (session *sess);
guint32 dcc_get_my_address (void);
guint32 dcc_get_my_address (session *sess);
void dcc_get_with_destfile (struct DCC *dcc, char *utf8file);
#endif
......@@ -313,7 +313,6 @@ struct hexchatprefs
/* these are the private variables */
guint32 local_ip;
guint32 dcc_ip;
unsigned int wait_on_exit; /* wait for logs to be flushed to disk IF we're connected */
......@@ -482,6 +481,10 @@ typedef struct server
int proxy_sok4;
int proxy_sok6;
int id; /* unique ID number (for plugin API) */
/* dcc_ip moved from hexchatprefs to make it per-server */
guint32 dcc_ip;
#ifdef USE_OPENSSL
SSL_CTX *ctx;
SSL *ssl;
......
......@@ -1420,7 +1420,7 @@ inbound_foundip (session *sess, char *ip, const message_tags_data *tags_data)
HostAddr = gethostbyname (ip);
if (HostAddr)
{
prefs.dcc_ip = ((struct in_addr *) HostAddr->h_addr)->s_addr;
sess->server->dcc_ip = ((struct in_addr *) HostAddr->h_addr)->s_addr;
EMIT_SIGNAL_TIMESTAMP (XP_TE_FOUNDIP, sess->server->server_session,
inet_ntoa (*((struct in_addr *) HostAddr->h_addr)),
NULL, NULL, NULL, 0, tags_data->timestamp);
......
......@@ -93,10 +93,6 @@ endif
if get_option('with-plugin')
common_deps += libgmodule_dep
common_cflags += '-DHEXCHATLIBDIR="@0@"'.format(join_paths(get_option('prefix'),
get_option('libdir'),
'hexchat/plugins'))
install_headers('hexchat-plugin.h')
endif
......
......@@ -735,6 +735,8 @@ handle_mode (server * serv, char *word[], char *word_eol[],
if (!(*word[i + offset]))
break;
num_args++;
if (word[i + offset][0] == ':')
break;
}
/* count the number of modes (without the -/+ chars */
......@@ -765,7 +767,7 @@ handle_mode (server * serv, char *word[], char *word_eol[],
if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args + 1))
{
arg++;
argstr = word[arg + offset];
argstr = STRIP_COLON(word, word_eol, arg+offset);
}
handle_single_mode (&mr, sign, *modes, nick, chan,
argstr, numeric_324 || prefs.hex_irc_raw_modes,
......
......@@ -3287,7 +3287,7 @@ cmd_send (struct session *sess, char *tbuf, char *word[], char *word_eol[])
if (!word[2][0])
return FALSE;
addr = dcc_get_my_address ();
addr = dcc_get_my_address (sess);
if (addr == 0)
{
/* use the one from our connected server socket */
......
......@@ -714,7 +714,7 @@ process_numeric (session * sess, int n,
break;
case 333:
inbound_topictime (serv, word[4], word[5], atol (word[6]), tags_data);
inbound_topictime (serv, word[4], word[5], atol (STRIP_COLON(word, word_eol, 6)), tags_data);
break;
#if 0
......@@ -726,7 +726,7 @@ process_numeric (session * sess, int n,
#endif
case 341: /* INVITE ACK */
EMIT_SIGNAL_TIMESTAMP (XP_TE_UINVITE, sess, word[4], word[5],
EMIT_SIGNAL_TIMESTAMP (XP_TE_UINVITE, sess, word[4], STRIP_COLON(word, word_eol, 5),
serv->servername, NULL, 0, tags_data->timestamp);
break;
......@@ -1142,7 +1142,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
{
case WORDL('A','C','C','O'):
inbound_account (serv, nick, word[3], tags_data);
inbound_account (serv, nick, STRIP_COLON(word, word_eol, 3), tags_data);
return;
case WORDL('A', 'U', 'T', 'H'):
......@@ -1150,7 +1150,7 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
return;
case WORDL('C', 'H', 'G', 'H'):
inbound_user_info (sess, NULL, word[3], word[4], NULL, nick, NULL,
inbound_user_info (sess, NULL, word[3], STRIP_COLON(word, word_eol, 4), NULL, nick, NULL,
NULL, 0xff, tags_data);
return;
......
......@@ -28,6 +28,8 @@
(time_t)0, /* timestamp */ \
}
#define STRIP_COLON(word, word_eol, idx) (word)[(idx)][0] == ':' ? (word_eol)[(idx)]+1 : (word)[(idx)]
/* Message tag information that might be passed along with a server message
*
* See http://ircv3.atheme.org/specification/capability-negotiation-3.1
......
......@@ -166,9 +166,6 @@ static const struct defaultserver def[] =
/* irc. points to chat. but many users and urls still reference it */
{0, "irc.freenode.net"},
{"Furnet", 0, 0, 0, 0, 0, TRUE},
{0, "irc.furnet.org"},
{"GalaxyNet", 0},
{0, "irc.galaxynet.org"},
......@@ -196,6 +193,11 @@ static const struct defaultserver def[] =
#endif
{0, "irc.globalgamers.net"},
#ifdef USE_OPENSSL
{"hackint", 0, 0, 0, LOGIN_SASL, 0, TRUE},
{0, "irc.hackint.org"},
#endif
{"Hashmark", 0},
{0, "irc.hashmark.net"},
......
......@@ -293,10 +293,10 @@ create_input_style (GtkStyle *style)
GtkSettings *settings = gtk_settings_get_default ();
char *theme_name;
/* gnome-themes-standard 3.20 relies on images to do theming
/* gnome-themes-standard 3.20+ relies on images to do theming
* so we have to override that. */
g_object_get (settings, "gtk-theme-name", &theme_name, NULL);
if (g_str_has_prefix (theme_name, "Adwaita"))
if (g_str_has_prefix (theme_name, "Adwaita") || g_str_has_prefix (theme_name, "Yaru"))
gtk_rc_parse_string (adwaita_workaround_rc);
g_free (theme_name);
......
......@@ -64,6 +64,8 @@
<LuaShare Include="$(DepsRoot)\share\lua\**\*.lua" />
<LuaShare Include="$(DepsRoot)\share\lua\**\**\*.lua" />
<Typelib Include="$(DepsRoot)\lib\girepository-1.0\*.typelib" />
<None Include="$(Python3Path)\Lib\site-packages\_cffi_backend.*.pyd" />
<None Include="$(Python2Path)\Lib\site-packages\_cffi_backend.pyd" />
<Engines Include="$(DepsRoot)\lib\gtk-2.0\i686-pc-vs14\engines\**\*" />
......@@ -91,6 +93,9 @@
<Copy SourceFiles="@(LuaShare)" DestinationFiles="@(LuaShare->'$(HexChatRel)\share\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(LuaLib)" DestinationFiles="@(LuaLib->'$(HexChatRel)\lib\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(Typelib)" DestinationFiles="@(Typelib->'$(HexChatRel)\lib\girepository-1.0\%(Filename)%(Extension)')" />
<Copy SourceFiles="..\..\plugins\python\xchat.py" DestinationFolder="$(HexChatRel)\python" />
<Copy SourceFiles="..\..\plugins\python\hexchat.py" DestinationFolder="$(HexChatRel)\python" />
<Copy SourceFiles="..\..\plugins\python\_hexchat.py" DestinationFolder="$(HexChatRel)\python" />
<WriteLinesToFile File="$(HexChatRel)portable-mode" Lines="2" Overwrite="true" />
......
......@@ -164,6 +164,7 @@ Source: "lib\girepository-1.0\*.typelib"; DestDir: "{app}\lib\girepository-1.0";
Source: "share\lua\*.lua"; DestDir: "{app}\share\lua"; Flags: ignoreversion; Components: langs\lua
Source: "share\lua\lgi\*.lua"; DestDir: "{app}\share\lua\lgi"; Flags: ignoreversion; Components: langs\lua
Source: "share\lua\lgi\override\*.lua"; DestDir: "{app}\share\lua\lgi\override"; Flags: ignoreversion; Components: langs\lua
Source: "plugins\hclua.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\lua
Source: "plugins\hcchecksum.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\checksum
Source: "plugins\hcexec.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\exec
......@@ -175,11 +176,15 @@ Source: "WinSparkle.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: pl
Source: "plugins\hcwinamp.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\winamp
Source: "share\system.png"; DestDir: "{app}\share"; Flags: ignoreversion; Components: plugins\sysinfo
Source: "plugins\hcsysinfo.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\sysinfo
Source: "plugins\hcperl.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\perl
Source: "python\*.py"; DestDir: "{app}\python"; Flags: ignoreversion; Components: langs\python
Source: "plugins\hcpython2.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\python\python2
Source: "_cffi_backend.pyd"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\python\python2
Source: "plugins\hcpython3.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\python\python3
Source: "plugins\hcperl.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\perl
Source: "plugins\hclua.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: langs\lua
Source: "_cffi_backend.cp3*.pyd"; DestDir: "{app}"; Flags: ignoreversion; Components: langs\python\python3
Source: "hexchat.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
Source: "hexchat-text.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xctext
......