From b4a3455acc6705f15c85c00f7e976f1c60addc70 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 29 Oct 2013 11:36:31 -0500 Subject: [PATCH 001/656] fifo tweaks for tracking user count --- src/mod/applications/mod_fifo/mod_fifo.c | 64 +++++++++++++++++++++--- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 3c6bc7a169..e5c12c0998 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1067,7 +1067,7 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses switch_channel_event_set_data(consumer_channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", MANUAL_QUEUE_NAME); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "bridge-consumer-stop"); - if (use_count) { + if (outbound_id) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", outbound_id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", use_count); } @@ -2218,7 +2218,7 @@ SWITCH_STANDARD_API(fifo_add_outbound_function) } -static void dec_use_count(switch_core_session_t *session, switch_bool_t send_event) +static void dec_use_count(switch_core_session_t *session, const char *type) { char *sql; const char *outbound_id = NULL; @@ -2226,8 +2226,6 @@ static void dec_use_count(switch_core_session_t *session, switch_bool_t send_eve long now = (long) switch_epoch_time_now(NULL); switch_channel_t *channel = switch_core_session_get_channel(session); - do_unbridge(session, NULL); - if ((outbound_id = switch_channel_get_variable(channel, "fifo_outbound_uuid"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s untracking call on uuid %s!\n", switch_channel_get_name(channel), outbound_id); @@ -2242,11 +2240,14 @@ static void dec_use_count(switch_core_session_t *session, switch_bool_t send_eve fifo_dec_use_count(outbound_id); } - if (send_event) { + do_unbridge(session, NULL); + + if (type) { if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", MANUAL_QUEUE_NAME); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "channel-consumer-stop"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Type", type); if (outbound_id) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", outbound_id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", fifo_get_use_count(outbound_id)); @@ -2262,7 +2263,7 @@ static switch_status_t hanguphook(switch_core_session_t *session) switch_channel_state_t state = switch_channel_get_state(channel); if (state >= CS_HANGUP && !switch_channel_test_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_DID_HOOK)) { - dec_use_count(session, SWITCH_TRUE); + dec_use_count(session, "manual"); switch_core_event_hook_remove_state_change(session, hanguphook); switch_channel_set_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_DID_HOOK); } @@ -2325,6 +2326,9 @@ SWITCH_STANDARD_APP(fifo_track_call_function) switch_channel_event_set_data(channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", MANUAL_QUEUE_NAME); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "channel-consumer-start"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", data); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", fifo_get_use_count(data)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Type", "manual"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-CID-Name", cid_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-CID-Number", cid_number); switch_event_fire(&event); @@ -2729,16 +2733,33 @@ SWITCH_STANDARD_APP(fifo_function) const char *url = NULL; const char *caller_uuid = NULL; const char *outbound_id = switch_channel_get_variable(channel, "fifo_outbound_uuid"); + switch_event_t *event; + const char *cid_name = NULL, *cid_number = NULL; //const char *track_use_count = switch_channel_get_variable(channel, "fifo_track_use_count"); //int do_track = switch_true(track_use_count); if (switch_core_event_hook_remove_receive_message(session, messagehook) == SWITCH_STATUS_SUCCESS) { - dec_use_count(session, SWITCH_FALSE); + dec_use_count(session, NULL); switch_core_event_hook_remove_state_change(session, hanguphook); switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_TRACKING); } + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { + cid_name = switch_channel_get_variable(channel, "callee_id_name"); + cid_number = switch_channel_get_variable(channel, "callee_id_number"); + + if (!cid_name) { + cid_name = switch_channel_get_variable(channel, "destination_number"); + } + if (!cid_number) { + cid_number = cid_name; + } + } else { + cid_name = switch_channel_get_variable(channel, "caller_id_name"); + cid_number = switch_channel_get_variable(channel, "caller_id_number"); + } + if (!zstr(strat_str)) { if (!strcasecmp(strat_str, "more_ppl")) { strat = STRAT_MORE_PPL; @@ -3148,6 +3169,22 @@ SWITCH_STANDARD_APP(fifo_function) } + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "channel-consumer-start"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Type", "onhook"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-CID-Name", cid_name); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-CID-Number", cid_number); + if (outbound_id) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", outbound_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", fifo_get_use_count(outbound_id)); + } + switch_event_fire(&event); + } + + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]); @@ -3221,6 +3258,19 @@ SWITCH_STANDARD_APP(fifo_function) } + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", arg_fifo_name); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "channel-consumer-stop"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Type", "onhook"); + if (outbound_id) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", outbound_id); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", fifo_get_use_count(outbound_id)); + } + switch_event_fire(&event); + } + del_bridge_call(switch_core_session_get_uuid(session)); del_bridge_call(switch_core_session_get_uuid(other_session)); From 1844058b593ffd6c900d110c10e36fc0542699bb Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 29 Oct 2013 12:58:28 -0500 Subject: [PATCH 002/656] Allow proxy media on pickup endpoint --- src/mod/applications/mod_dptools/mod_dptools.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 8d7b5c6f37..b5b7718231 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -3622,6 +3622,9 @@ static switch_call_cause_t pickup_outgoing_channel(switch_core_session_t *sessio switch_core_session_set_private(nsession, tech_pvt); nchannel = switch_core_session_get_channel(nsession); + switch_channel_set_cap(nchannel, CC_PROXY_MEDIA); + switch_channel_set_cap(nchannel, CC_BYPASS_MEDIA); + caller_profile = switch_caller_profile_clone(nsession, outbound_profile); switch_channel_set_caller_profile(nchannel, caller_profile); From abc230ed50d1e3b1ff645b07815057114c831519 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 29 Oct 2013 12:58:53 -0500 Subject: [PATCH 003/656] FS-5909 use correct ip in patched sdp --- src/switch_core_media.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 5370919774..3ab77c565b 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6511,11 +6511,11 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) strncpy(q, p, 7); p += 7; q += 7; - strncpy(q, strchr(a_engine->codec_params.local_sdp_ip, ':') ? "6 " : "4 ", 2); + strncpy(q, strchr(a_engine->codec_params.adv_sdp_ip, ':') ? "6 " : "4 ", 2); p +=2; q +=2; - strncpy(q, a_engine->codec_params.local_sdp_ip, strlen(a_engine->codec_params.local_sdp_ip)); - q += strlen(a_engine->codec_params.local_sdp_ip); + strncpy(q, a_engine->codec_params.adv_sdp_ip, strlen(a_engine->codec_params.adv_sdp_ip)); + q += strlen(a_engine->codec_params.adv_sdp_ip); while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) { if (p >= pe) { From 88a13f1fc2cc56279717d15abe138a1111a48fc0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 29 Oct 2013 13:40:27 -0500 Subject: [PATCH 004/656] update err msg --- src/switch_rtp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4439d1d0be..17c719b8d9 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2965,7 +2965,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session "Starting timer [%s] %d bytes per %dms\n", timer_name, samples_per_interval, ms_per_packet / 1000); } else { memset(&rtp_session->timer, 0, sizeof(rtp_session->timer)); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error starting timer [%s], async RTP disabled\n", timer_name); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, + "Error Starting timer [%s] %d bytes per %dms, async RTP disabled\n", timer_name, samples_per_interval, ms_per_packet / 1000); switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER); } } else { From c32bd46853a60a43176418c0206fbf76a7680a5d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 20:30:17 +0500 Subject: [PATCH 005/656] FS-5924 --resolve --- src/switch_core_io.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 47f6289a73..b1b42c7f1f 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -295,6 +295,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -357,6 +359,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi if (session->bugs && switch_test_flag((*frame), SFF_CNG)) { switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -651,6 +655,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -700,6 +706,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -866,6 +874,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi int prune = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -936,6 +946,8 @@ static switch_status_t perform_write(switch_core_session_t *session, switch_fram switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -1237,6 +1249,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { switch_bool_t ok = SWITCH_TRUE; + if (!bp->ready) { continue; } From e2e8a57d9d9e00c868d8b875472bf4dfad6d057c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 14:08:27 -0500 Subject: [PATCH 006/656] add ring_wait callstate for devstate interface --- src/include/switch_core.h | 1 + src/include/switch_types.h | 1 + src/switch_channel.c | 41 ++++++++++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index c203f84dbc..43c872b5cf 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -109,6 +109,7 @@ typedef struct switch_device_stats_s { uint32_t early; uint32_t early_in; uint32_t early_out; + uint32_t ring_wait; } switch_device_stats_t; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 5c049ddd0a..8d042eae11 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1140,6 +1140,7 @@ typedef enum { CCS_EARLY, CCS_ACTIVE, CCS_HELD, + CCS_RING_WAIT, CCS_HANGUP, CCS_UNHOLD } switch_channel_callstate_t; diff --git a/src/switch_channel.c b/src/switch_channel.c index e96bbc78d7..4e5121a034 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -240,6 +240,7 @@ static struct switch_callstate_table CALLSTATE_CHART[] = { {"EARLY", CCS_EARLY}, {"ACTIVE", CCS_ACTIVE}, {"HELD", CCS_HELD}, + {"RING_WAIT", CCS_RING_WAIT}, {"HANGUP", CCS_HANGUP}, {"UNHOLD", CCS_UNHOLD}, {NULL, 0} @@ -1757,6 +1758,10 @@ SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, sw channel->flags[flag] = value; switch_mutex_unlock(channel->flag_mutex); + if (flag == CF_ORIGINATOR && switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_up_nosig(channel)) { + switch_channel_set_callstate(channel, CCS_RING_WAIT); + } + if (HELD) { switch_hold_record_t *hr; const char *brto = switch_channel_get_partner_uuid(channel); @@ -1939,6 +1944,10 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch switch_mutex_unlock(channel->profile_mutex); } + if (flag == CF_ORIGINATOR && switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_up_nosig(channel)) { + switch_channel_set_callstate(channel, CCS_ACTIVE); + } + if (flag == CF_OUTBOUND) { switch_channel_set_variable(channel, "is_outbound", NULL); } @@ -4708,6 +4717,8 @@ static void fetch_device_stats(switch_device_record_t *drec) } else { drec->stats.ringing_out++; } + } else if (np->callstate == CCS_RING_WAIT) { + drec->stats.ring_wait++; } else if (np->callstate == CCS_HANGUP) { drec->stats.hup++; if (np->direction == SWITCH_CALL_DIRECTION_INBOUND) { @@ -4871,7 +4882,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ drec->state = SDS_HANGUP; } else { if (drec->stats.active == 0) { - if ((drec->stats.ringing_out + drec->stats.early_out) > 0) { + if ((drec->stats.ringing_out + drec->stats.early_out) > 0 || drec->stats.ring_wait > 0) { drec->state = SDS_RINGING; } else { if (drec->stats.held > 0) { @@ -4899,25 +4910,32 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ switch(drec->state) { case SDS_RINGING: - drec->ring_start = switch_micro_time_now(); - drec->ring_stop = 0; + if (!drec->ring_start) { + drec->ring_start = switch_micro_time_now(); + drec->ring_stop = 0; + } break; case SDS_ACTIVE: case SDS_ACTIVE_MULTI: - if (drec->active_start && drec->last_state != SDS_HELD) { - drec->active_stop = switch_micro_time_now(); - } else if (!drec->active_start) { + if (!drec->active_start) { drec->active_start = switch_micro_time_now(); + drec->active_stop = 0; + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "SET START start:%ld stop:%ld\n", drec->active_start, drec->active_stop); } break; case SDS_HELD: - drec->hold_start = switch_micro_time_now(); - drec->hold_stop = 0; - default: - if (drec->active_start && drec->last_state != SDS_HELD) { - drec->active_stop = switch_micro_time_now(); + if (!drec->hold_start) { + drec->hold_start = switch_micro_time_now(); + drec->hold_stop = 0; } break; + default: + break; + } + + if (drec->active_start && drec->state != SDS_ACTIVE && drec->state != SDS_ACTIVE_MULTI) { + drec->active_stop = switch_micro_time_now(); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "SET STOP start:%ld stop:%ld\n", drec->active_start, drec->active_stop); } if (drec->ring_start && !drec->ring_stop && drec->state != SDS_RINGING) { @@ -4979,6 +4997,7 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ if (drec->state == SDS_ACTIVE || drec->state == SDS_ACTIVE_MULTI) { drec->active_start = switch_micro_time_now(); } + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "SET START start:%ld stop:%ld\n", drec->active_start, drec->active_stop); } if (drec->hold_stop) { From 30f7480c9cd199301062197c3fa844bb0bdca9ca Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 14:21:21 -0500 Subject: [PATCH 007/656] FS-5680 revert, set this variable globally in vars.xml instead --- src/switch_core_media.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 3ab77c565b..d435b1173a 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2804,9 +2804,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) { got_crypto = 1; - if (sdp_type == SDP_TYPE_REQUEST) { - switch_channel_set_variable(session->channel, "answer_delay", "2500"); - } } } } From b5d53b63417e0532ee310df0bdf6d9d2078550a9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 17:26:06 -0500 Subject: [PATCH 008/656] remove_debug --- src/switch_channel.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index 4e5121a034..aa73b4d2fc 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -4920,7 +4920,6 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ if (!drec->active_start) { drec->active_start = switch_micro_time_now(); drec->active_stop = 0; - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "SET START start:%ld stop:%ld\n", drec->active_start, drec->active_stop); } break; case SDS_HELD: @@ -4935,7 +4934,6 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ if (drec->active_start && drec->state != SDS_ACTIVE && drec->state != SDS_ACTIVE_MULTI) { drec->active_stop = switch_micro_time_now(); - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "SET STOP start:%ld stop:%ld\n", drec->active_start, drec->active_stop); } if (drec->ring_start && !drec->ring_stop && drec->state != SDS_RINGING) { @@ -4997,7 +4995,6 @@ static void switch_channel_check_device_state(switch_channel_t *channel, switch_ if (drec->state == SDS_ACTIVE || drec->state == SDS_ACTIVE_MULTI) { drec->active_start = switch_micro_time_now(); } - switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "SET START start:%ld stop:%ld\n", drec->active_start, drec->active_stop); } if (drec->hold_stop) { From ca893da3fb3f0899c098d91655f6f5c2f5f5ccfe Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 17:52:49 -0500 Subject: [PATCH 009/656] FS-5923 --- src/mod/applications/mod_esf/mod_esf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index bc04991bee..38badb3301 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -201,7 +201,7 @@ SWITCH_STANDARD_APP(bcast_function) mcast_port, 0, 8000, - 20, flags, "soft", &err, switch_core_session_get_pool(session)); + 2000, flags, "soft", &err, switch_core_session_get_pool(session)); if (!switch_rtp_ready(rtp_session)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n"); From 57f53064107bde327fb46915cb50226bd19132b0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 18:09:11 -0500 Subject: [PATCH 010/656] FS-4067 missed a 0 --- src/mod/applications/mod_esf/mod_esf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index 38badb3301..3bd08d3467 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -201,7 +201,7 @@ SWITCH_STANDARD_APP(bcast_function) mcast_port, 0, 8000, - 2000, flags, "soft", &err, switch_core_session_get_pool(session)); + 20000, flags, "soft", &err, switch_core_session_get_pool(session)); if (!switch_rtp_ready(rtp_session)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n"); From ee0a7f0ecf8b021ef54d9f7b1be492d667ca6295 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 18:13:04 -0500 Subject: [PATCH 011/656] FS-4067 missed another val --- src/mod/applications/mod_esf/mod_esf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index 3bd08d3467..42a760b45b 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -200,7 +200,7 @@ SWITCH_STANDARD_APP(bcast_function) mcast_ip, mcast_port, 0, - 8000, + 160, 20000, flags, "soft", &err, switch_core_session_get_pool(session)); if (!switch_rtp_ready(rtp_session)) { From bd41690d890fc99a0b38743acf1ec0329e29ad15 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 19:16:23 -0500 Subject: [PATCH 012/656] FS-4067 this should make g722 work --- src/mod/applications/mod_esf/mod_esf.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index 42a760b45b..f6a9191877 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -30,6 +30,7 @@ * */ #include +#include SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load); SWITCH_MODULE_DEFINITION(mod_esf, mod_esf_load, NULL, NULL); @@ -168,7 +169,7 @@ SWITCH_STANDARD_APP(bcast_function) if (ready == SEND_TYPE_RTP) { if (read_impl.ianacode != 0) { if (switch_core_codec_init(&codec, - "PCMU", + "L16", NULL, 8000, 20, @@ -237,7 +238,22 @@ SWITCH_STANDARD_APP(bcast_function) continue; } if (ready == SEND_TYPE_RTP) { + short *dbuf; + unsigned char *ebuf; + uint32_t i; + unsigned char encoded_data[4192]; + + dbuf = read_frame->data; + ebuf = encoded_data; + + for (i = 0; i < read_frame->datalen / sizeof(short); i++) { + ebuf[i] = linear_to_ulaw(dbuf[i]); + } + read_frame->data = encoded_data; + read_frame->datalen = read_frame->datalen / 2; switch_rtp_write_frame(rtp_session, read_frame); + read_frame->data = dbuf; + read_frame->datalen = read_frame->datalen * 2; } else { bytes = read_frame->packetlen; switch_socket_sendto(socket, audio_addr, 0, read_frame->packet, &bytes); From 75ad91e185d35789becb9c370f3f0c6cc6571365 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 30 Oct 2013 20:26:01 -0500 Subject: [PATCH 013/656] FS-5844 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 36 ++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index e2207d2c6d..c7565094b0 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6438,7 +6438,41 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } break; case nua_callstate_ready: - if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) && + if (switch_channel_test_flag(channel, CF_PROXY_MODE) && r_sdp) { + char ibuf[35] = "", pbuf[35] = ""; + const char *ptr; + + if ((ptr = switch_stristr("c=IN IP4", r_sdp))) { + int i = 0; + + ptr += 8; + + while(*ptr == ' ') { + ptr++; + } + while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') { + ibuf[i++] = *ptr++; + } + + switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, ibuf); + } + + if ((ptr = switch_stristr("m=audio", r_sdp))) { + int i = 0; + + ptr += 7; + + while(*ptr == ' ') { + ptr++; + } + while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') { + pbuf[i++] = *ptr++; + } + + switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, pbuf); + } + + } else if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) && r_sdp && (!is_dup_sdp || sofia_test_flag(tech_pvt, TFLAG_NEW_SDP)) && switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) && !sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)) { /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */ uint8_t match = 0; From dddbcacf0e206906541a5d442d138d1008f5bb6e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 Oct 2013 09:28:31 -0500 Subject: [PATCH 014/656] FS-5925 --resolve --- src/mod/applications/mod_conference/mod_conference.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 863e4c727b..61a50854ea 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -33,6 +33,7 @@ * Joao Mesquita * Raymond Chandler * Seven Du + * Emmanuel Schmidbauer * * mod_conference.c -- Software Conference Bridge * @@ -4083,6 +4084,7 @@ static void conference_loop_output(conference_member_t *member) const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); const char *maxwait = switch_channel_get_variable(channel, "conference_auto_outcall_maxwait"); + const char *delimiter_val = switch_channel_get_variable(channel, "conference_auto_outcall_delimiter"); int to = 60; int wait_sec = 2; int loops = 0; @@ -4109,7 +4111,12 @@ static void conference_loop_output(conference_member_t *member) int x = 0; switch_assert(cpstr); - argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + if (!zstr(delimiter_val) && strlen(delimiter_val) == 1) { + char delimiter = *delimiter_val; + argc = switch_separate_string(cpstr, delimiter, argv, (sizeof(argv) / sizeof(argv[0]))); + } else { + argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + } for (x = 0; x < argc; x++) { char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); switch_assert(dial_str); From ecedd2d21c07190aa7fd2a068d0864d8874ce6cf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 Oct 2013 10:35:53 -0500 Subject: [PATCH 015/656] FS-5844 --- src/mod/endpoints/mod_sofia/sofia.c | 71 ++++++++++++++--------------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index c7565094b0..f2194487d4 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5960,7 +5960,40 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (r_sdp) { - if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { + if (switch_channel_test_flag(channel, CF_PROXY_MODE) && r_sdp) { + char ibuf[35] = "", pbuf[35] = ""; + const char *ptr; + + if ((ptr = switch_stristr("c=IN IP4", r_sdp))) { + int i = 0; + + ptr += 8; + + while(*ptr == ' ') { + ptr++; + } + while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') { + ibuf[i++] = *ptr++; + } + + switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, ibuf); + } + + if ((ptr = switch_stristr("m=audio", r_sdp))) { + int i = 0; + + ptr += 7; + + while(*ptr == ' ') { + ptr++; + } + while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') { + pbuf[i++] = *ptr++; + } + + switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, pbuf); + } + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "PROXY MEDIA"); } @@ -6438,41 +6471,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } break; case nua_callstate_ready: - if (switch_channel_test_flag(channel, CF_PROXY_MODE) && r_sdp) { - char ibuf[35] = "", pbuf[35] = ""; - const char *ptr; - - if ((ptr = switch_stristr("c=IN IP4", r_sdp))) { - int i = 0; - - ptr += 8; - - while(*ptr == ' ') { - ptr++; - } - while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') { - ibuf[i++] = *ptr++; - } - - switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, ibuf); - } - - if ((ptr = switch_stristr("m=audio", r_sdp))) { - int i = 0; - - ptr += 7; - - while(*ptr == ' ') { - ptr++; - } - while(*ptr && *ptr != ' ' && *ptr != '\r' && *ptr != '\n') { - pbuf[i++] = *ptr++; - } - - switch_channel_set_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, pbuf); - } - - } else if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) && + if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA) && r_sdp && (!is_dup_sdp || sofia_test_flag(tech_pvt, TFLAG_NEW_SDP)) && switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO) && !sofia_test_flag(tech_pvt, TFLAG_NOSDP_REINVITE)) { /* sdp changed since 18X w sdp, we're supposed to ignore it but we, of course, were pressured into supporting it */ uint8_t match = 0; From 460b8014b9b186ddf1476ca89e00113999d95d35 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 Oct 2013 11:21:34 -0500 Subject: [PATCH 016/656] add channel to logline --- libs/freetdm/mod_freetdm/mod_freetdm.c | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 865b52363f..3ac9bd0a36 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -719,14 +719,14 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch name = switch_channel_get_name(channel); if (!tech_pvt->ftdmchan) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name); return SWITCH_STATUS_FALSE; } span_id = ftdm_channel_get_span_id(tech_pvt->ftdmchan); chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan); if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id); return SWITCH_STATUS_FALSE; } @@ -760,7 +760,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch } if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id); goto fail; } @@ -768,7 +768,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, chunk); if (status == FTDM_FAIL) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); goto fail; } @@ -776,7 +776,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch if (!switch_test_flag(tech_pvt, TFLAG_HOLD)) { total_to -= chunk; if (total_to <= 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Too many timeouts while waiting I/O in channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "Too many timeouts while waiting I/O in channel %s device %d:%d!\n", name, span_id, chan_id); goto fail; } } @@ -789,9 +789,9 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch len = tech_pvt->read_frame.buflen; if (ftdm_channel_read(tech_pvt->ftdmchan, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); if (++tech_pvt->read_error > FTDM_MAX_READ_WRITE_ERRORS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "too many I/O read errors on channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "too many I/O read errors on channel %s device %d:%d!\n", name, span_id, chan_id); goto fail; } } else { @@ -812,7 +812,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch for (p = dtmf; p && *p; p++) { if (is_dtmf(*p)) { _dtmf.digit = *p; - ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id); switch_channel_queue_dtmf(channel, &_dtmf); } } @@ -821,7 +821,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch return SWITCH_STATUS_SUCCESS; fail: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "clearing IO in channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "clearing IO in channel %s device %d:%d!\n", name, span_id, chan_id); switch_clear_flag_locked(tech_pvt, TFLAG_IO); return SWITCH_STATUS_GENERR; } @@ -844,7 +844,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc name = switch_channel_get_name(channel); if (!tech_pvt->ftdmchan) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "no ftdmchan set in channel %s!\n", name); return SWITCH_STATUS_FALSE; } @@ -852,7 +852,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc chan_id = ftdm_channel_get_id(tech_pvt->ftdmchan); if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_DEAD is set in channel %s device %d:%d!\n", name, span_id, chan_id); return SWITCH_STATUS_FALSE; } @@ -861,7 +861,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc } if (!switch_test_flag(tech_pvt, TFLAG_IO)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "TFLAG_IO is not set in channel %s device %d:%d!\n", name, span_id, chan_id); goto fail; } @@ -879,15 +879,15 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10); if (!(wflags & FTDM_WRITE)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id); return SWITCH_STATUS_SUCCESS; } len = frame->datalen; if (ftdm_channel_write(tech_pvt->ftdmchan, frame->data, frame->buflen, &len) != FTDM_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id); if (++tech_pvt->write_error > FTDM_MAX_READ_WRITE_ERRORS) { - switch_log_printf(SWITCH_CHANNEL_LOG, + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Too many I/O write errors on channel %s device %d:%d!\n", name, span_id, chan_id); goto fail; } @@ -898,7 +898,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc return SWITCH_STATUS_SUCCESS; fail: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error writing to channel %s device %d:%d!\n", name, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Error writing to channel %s device %d:%d!\n", name, span_id, chan_id); switch_clear_flag_locked(tech_pvt, TFLAG_IO); return SWITCH_STATUS_GENERR; @@ -1239,7 +1239,7 @@ static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t tech_init(hdata->tech_pvt, hdata->new_session, fchan, caller_data); snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name); switch_channel_set_name(channel, name); switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(fchan)); switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id); @@ -1267,7 +1267,7 @@ static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t return FTDM_BREAK; } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Attached session %s to channel %d:%d\n", sess_uuid, span_id, chan_id); + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Attached session %s to channel %d:%d\n", sess_uuid, span_id, chan_id); return FTDM_SUCCESS; } From a7dab0464d01c9ed4a333dd2f8528cce366e2e50 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 Oct 2013 11:37:46 -0500 Subject: [PATCH 017/656] FS-5933 --resolve --- src/switch_core_media.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d435b1173a..d18b648546 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3033,19 +3033,21 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bah HUMBUG! Sticking with %s@%uh@%ui\n", imp->iananame, imp->samples_per_second, imp->microseconds_per_packet / 1000); - } else if (!near_match) { - if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || map->rm_rate != codec_rate) { + } else if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || map->rm_rate != codec_rate) { + /* ptime does not match */ + match = 0; + + /* save first near_match */ + if (!near_match) { near_rate = map->rm_rate; near_match = imp; near_map = mmap = map; - match = 0; if (switch_true(switch_channel_get_variable_dup(channel, "rtp_negotiate_near_match", SWITCH_FALSE, -1))) { goto near_match; } - - continue; } + continue; } mimp = imp; mmap = map; @@ -3080,10 +3082,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (num) { mimp = search[0]; - mmap = map; } else { mimp = near_match; - mmap = map; } if (!maxptime || mimp->microseconds_per_packet / 1000 <= maxptime) { From f532640c4964c733e1ea262c26310fd025a229a8 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Fri, 1 Nov 2013 02:44:11 +0800 Subject: [PATCH 018/656] Fixed an embedded assembly language constraint issue --- libs/spandsp/src/vector_int.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/spandsp/src/vector_int.c b/libs/spandsp/src/vector_int.c index 66166e52eb..c2ed12f98e 100644 --- a/libs/spandsp/src/vector_int.c +++ b/libs/spandsp/src/vector_int.c @@ -147,7 +147,7 @@ SPAN_DECLARE(int32_t) vec_dot_prodi16(const int16_t x[], const int16_t y[], int " emms;\n" : "=a" (z) : "S" (x), "D" (y), "a" (n) - : "cc" + : "cc", "rdx", "mm0", "mm1", "mm2" ); #elif defined(__GNUC__) && defined(SPANDSP_USE_MMX) && defined(__i386__) __asm__ __volatile__( @@ -245,7 +245,7 @@ SPAN_DECLARE(int32_t) vec_dot_prodi16(const int16_t x[], const int16_t y[], int " emms;\n" : "=a" (z) : "S" (x), "D" (y), "a" (n) - : "cc" + : "cc", "edx", "mm0", "mm1", "mm2" ); #else int i; @@ -436,7 +436,7 @@ SPAN_DECLARE(int32_t) vec_min_maxi16(const int16_t x[], int n, int16_t out[]) " emms;\n" : "=a" (max) : "S" (x), "a" (n), "d" (out), [lower] "m" (lower_bound), [upper] "m" (upper_bound) - : "ecx" + : "ecx", "mm0", "mm1", "mm2", "mm3", "mm4" ); #elif defined(__GNUC__) && defined(SPANDSP_USE_MMX) && defined(__i386__) static const int32_t lower_bound = 0x80008000; @@ -589,7 +589,7 @@ SPAN_DECLARE(int32_t) vec_min_maxi16(const int16_t x[], int n, int16_t out[]) " emms;\n" : "=a" (max) : "S" (x), "a" (n), "d" (out), [lower] "m" (lower_bound), [upper] "m" (upper_bound) - : "ecx" + : "ecx", "mm0", "mm1", "mm2", "mm3", "mm4" ); #else int i; From c8b80cced6906c912c421b43bdb75aa4ec5c8181 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 Oct 2013 14:08:43 -0500 Subject: [PATCH 019/656] FS-5930 --resolve this should suppress the message --- src/mod/formats/mod_local_stream/mod_local_stream.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index 6d91f9b653..bae5408014 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -311,16 +311,17 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void if (!is_open || used >= source->prebuf || (source->total && used > source->samples * 2)) { used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2); if (source->total) { - + uint32_t used = 0; switch_mutex_lock(source->mutex); for (cp = source->context_list; cp && RUNNING; cp = cp->next) { if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) { continue; } switch_mutex_lock(cp->audio_mutex); - if (switch_buffer_inuse(cp->audio_buffer) > source->samples * 768) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Leaking stream handle! [%s() %s:%d]\n", cp->func, cp->file, - cp->line); + used = switch_buffer_inuse(cp->audio_buffer); + if (used > source->samples * 768) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Flushing Stream Handle Buffer [%s() %s:%d] size: %u samples: %ld\n", + cp->func, cp->file, cp->line, used, (long)source->samples); switch_buffer_zero(cp->audio_buffer); } else { switch_buffer_write(cp->audio_buffer, dist_buf, used); From 4a8e9d634d4b1bbc191636c8221b02013b70c9e9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 1 Nov 2013 02:21:04 +0500 Subject: [PATCH 020/656] add ref counter to la --- src/switch_event.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index 0a0a532628..48743a7c30 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -3055,6 +3055,7 @@ struct switch_live_array_s { switch_live_array_command_handler_t command_handler; void *user_data; alias_node_t *aliases; + int refs; }; static switch_status_t la_broadcast(switch_live_array_t *la, cJSON **json) @@ -3215,9 +3216,21 @@ SWITCH_DECLARE(switch_status_t) switch_live_array_destroy(switch_live_array_t ** switch_live_array_t *la = *live_arrayP; switch_memory_pool_t *pool; alias_node_t *np; + int done = 0; *live_arrayP = NULL; + switch_mutex_lock(la->mutex); + if (la->refs) { + la->refs--; + } + if (la->refs) done = 1; + switch_mutex_unlock(la->mutex); + + if (done) { + return SWITCH_STATUS_SUCCESS; + } + pool = la->pool; switch_live_array_clear(la); @@ -3311,7 +3324,6 @@ SWITCH_DECLARE(switch_bool_t) switch_live_array_add_alias(switch_live_array_t *l return !exist; } - SWITCH_DECLARE(switch_status_t) switch_live_array_create(const char *event_channel, const char *name, switch_event_channel_id_t channel_id, switch_live_array_t **live_arrayP) { @@ -3346,6 +3358,10 @@ SWITCH_DECLARE(switch_status_t) switch_live_array_create(const char *event_chann switch_mutex_unlock(event_channel_manager.lamutex); } + switch_mutex_lock(la->mutex); + la->refs++; + switch_mutex_unlock(la->mutex); + *live_arrayP = la; return SWITCH_STATUS_SUCCESS; @@ -3559,14 +3575,16 @@ SWITCH_DECLARE(void) switch_live_array_parse_json(cJSON *json, switch_event_chan const char *sessid = cJSON_GetObjectCstr(json, "sessid"); if (command) { - switch_live_array_create(context, name, channel_id, &la); + if (switch_live_array_create(context, name, channel_id, &la) == SWITCH_STATUS_SUCCESS) { - if (!strcasecmp(command, "bootstrap")) { - switch_live_array_bootstrap(la, sessid, channel_id); - } else { - if (la->command_handler) { - la->command_handler(la, command, sessid, jla, la->user_data); + if (!strcasecmp(command, "bootstrap")) { + switch_live_array_bootstrap(la, sessid, channel_id); + } else { + if (la->command_handler) { + la->command_handler(la, command, sessid, jla, la->user_data); + } } + switch_live_array_destroy(&la); } } } From fd97365d4aad304360ee67c746f8eea3f4b95c18 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 1 Nov 2013 02:21:58 +0500 Subject: [PATCH 021/656] detect ca-bundle.crt for chain cert to use in dtls connections --- src/switch_rtp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 17c719b8d9..08b310c2c3 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2561,7 +2561,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d dtls->pvt = switch_core_sprintf(rtp_session->pool, "%s%s%s.key", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, DTLS_SRTP_FNAME); dtls->rsa = switch_core_sprintf(rtp_session->pool, "%s%s%s.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR, DTLS_SRTP_FNAME); - //dtls->ca = switch_core_sprintf(rtp_session->pool, "%s%sca-bundle.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR); + dtls->ca = switch_core_sprintf(rtp_session->pool, "%s%sca-bundle.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR); dtls->ssl_ctx = SSL_CTX_new(DTLSv1_method()); switch_assert(dtls->ssl_ctx); @@ -2604,7 +2604,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d return SWITCH_STATUS_FALSE; } - if (!zstr(dtls->ca) && (ret=SSL_CTX_load_verify_locations(dtls->ssl_ctx, dtls->ca, NULL)) != 1) { + if (!zstr(dtls->ca) && switch_file_exists(dtls->ca, rtp_session->pool) == SWITCH_STATUS_SUCCESS + && (ret = SSL_CTX_load_verify_locations(dtls->ssl_ctx, dtls->ca, NULL)) != 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS check chain cert failed [%d]\n", rtp_type(rtp_session) , SSL_get_error(dtls->ssl, ret)); From 5f239a5baea555218835552f137e64e0e43da76e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 Oct 2013 15:28:24 -0500 Subject: [PATCH 022/656] add channel logical direction --- src/include/switch_caller.h | 1 + src/include/switch_channel.h | 1 + src/switch_channel.c | 37 +++++++++++++++++++++++++++++++++--- src/switch_ivr_bridge.c | 4 ++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/include/switch_caller.h b/src/include/switch_caller.h index f0dc1c76fe..1fd5ecbd29 100644 --- a/src/include/switch_caller.h +++ b/src/include/switch_caller.h @@ -127,6 +127,7 @@ typedef struct profile_node_s { switch_memory_pool_t *pool; struct switch_caller_profile *next; switch_call_direction_t direction; + switch_call_direction_t logical_direction; profile_node_t *soft; char *uuid_str; char *clone_of; diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 234b692114..9e7c91f935 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -633,6 +633,7 @@ SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *app, switch_cha SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel); SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel); SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel); +SWITCH_DECLARE(switch_call_direction_t) switch_channel_logical_direction(switch_channel_t *channel); SWITCH_DECLARE(void) switch_channel_set_direction(switch_channel_t *channel, switch_call_direction_t direction); SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel); diff --git a/src/switch_channel.c b/src/switch_channel.c index aa73b4d2fc..21b9dedc6f 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -139,6 +139,7 @@ typedef enum { struct switch_channel { char *name; switch_call_direction_t direction; + switch_call_direction_t logical_direction; switch_queue_t *dtmf_queue; switch_queue_t *dtmf_log_queue; switch_mutex_t*dtmf_mutex; @@ -393,7 +394,7 @@ SWITCH_DECLARE(switch_channel_timetable_t *) switch_channel_get_timetable(switch SWITCH_DECLARE(void) switch_channel_set_direction(switch_channel_t *channel, switch_call_direction_t direction) { if (!switch_core_session_in_thread(channel->session)) { - channel->direction = direction; + channel->direction = channel->logical_direction = direction; } } @@ -402,6 +403,11 @@ SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_ return channel->direction; } +SWITCH_DECLARE(switch_call_direction_t) switch_channel_logical_direction(switch_channel_t *channel) +{ + return channel->logical_direction; +} + SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_call_direction_t direction, switch_memory_pool_t *pool) { switch_assert(pool != NULL); @@ -423,7 +429,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_alloc(switch_channel_t **channel, switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool); (*channel)->hangup_cause = SWITCH_CAUSE_NONE; (*channel)->name = ""; - (*channel)->direction = direction; + (*channel)->direction = (*channel)->logical_direction = direction; switch_channel_set_variable(*channel, "direction", switch_channel_direction(*channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"); return SWITCH_STATUS_SUCCESS; @@ -1762,6 +1768,20 @@ SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, sw switch_channel_set_callstate(channel, CCS_RING_WAIT); } + if (flag == CF_DIALPLAN) { + if (channel->direction == SWITCH_CALL_DIRECTION_INBOUND) { + channel->logical_direction = SWITCH_CALL_DIRECTION_OUTBOUND; + if (channel->device_node) { + channel->device_node->direction = SWITCH_CALL_DIRECTION_INBOUND; + } + } else { + channel->logical_direction = SWITCH_CALL_DIRECTION_INBOUND; + if (channel->device_node) { + channel->device_node->direction = SWITCH_CALL_DIRECTION_OUTBOUND; + } + } + } + if (HELD) { switch_hold_record_t *hr; const char *brto = switch_channel_get_partner_uuid(channel); @@ -1930,6 +1950,15 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch channel->flags[flag] = 0; switch_mutex_unlock(channel->flag_mutex); + if (flag == CF_DIALPLAN) { + if (channel->direction == SWITCH_CALL_DIRECTION_OUTBOUND) { + channel->logical_direction = SWITCH_CALL_DIRECTION_OUTBOUND; + if (channel->device_node) { + channel->device_node->direction = SWITCH_CALL_DIRECTION_INBOUND; + } + } + } + if (ACTIVE) { switch_channel_set_callstate(channel, CCS_UNHOLD); switch_mutex_lock(channel->profile_mutex); @@ -2615,6 +2644,7 @@ SWITCH_DECLARE(void) switch_channel_set_caller_profile(switch_channel_t *channel switch_assert(caller_profile != NULL); caller_profile->direction = channel->direction; + caller_profile->logical_direction = channel->logical_direction; uuid = switch_core_session_get_uuid(channel->session); if (!caller_profile->uuid || strcasecmp(caller_profile->uuid, uuid)) { @@ -2697,6 +2727,7 @@ SWITCH_DECLARE(void) switch_channel_set_hunt_caller_profile(switch_channel_t *ch channel->caller_profile->hunt_caller_profile = NULL; if (channel->caller_profile && caller_profile) { caller_profile->direction = channel->direction; + caller_profile->logical_direction = channel->logical_direction; channel->caller_profile->hunt_caller_profile = caller_profile; } switch_mutex_unlock(channel->profile_mutex); @@ -5038,7 +5069,7 @@ static void add_uuid(switch_device_record_t *drec, switch_channel_t *channel) node->uuid = switch_core_strdup(drec->pool, switch_core_session_get_uuid(channel->session)); node->parent = drec; node->callstate = channel->callstate; - node->direction = channel->direction == SWITCH_CALL_DIRECTION_INBOUND ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND; + node->direction = channel->logical_direction == SWITCH_CALL_DIRECTION_INBOUND ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND; channel->device_node = node; diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 356e03f43d..089301da0e 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1695,6 +1695,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_uuid_bridge(const char *originator_uu } } + if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) { + switch_channel_clear_flag(originatee_channel, CF_DIALPLAN); + } + cleanup_proxy_mode_a(originator_session); cleanup_proxy_mode_a(originatee_session); From b0d95efd09d010154a8422c611feb64c64a1e71f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 31 Oct 2013 17:22:09 -0500 Subject: [PATCH 023/656] dont byteswap the extended bit headers in the actual packet so it can properly echo back without modification --- src/switch_rtp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 08b310c2c3..325a41fd07 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4160,14 +4160,13 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (!rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && !rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] && rtp_session->recv_msg.header.version == 2 && rtp_session->recv_msg.header.x) { /* header extensions */ + uint16_t length; rtp_session->recv_msg.ext = (switch_rtp_hdr_ext_t *) rtp_session->recv_msg.body; + length = ntohs((uint16_t)rtp_session->recv_msg.ext->length); - rtp_session->recv_msg.ext->length = ntohs((uint16_t)rtp_session->recv_msg.ext->length); - rtp_session->recv_msg.ext->profile = ntohs((uint16_t)rtp_session->recv_msg.ext->profile); - - if (rtp_session->recv_msg.ext->length < SWITCH_RTP_MAX_BUF_LEN_WORDS) { - rtp_session->recv_msg.ebody = rtp_session->recv_msg.body + (rtp_session->recv_msg.ext->length * 4) + 4; + if (length < SWITCH_RTP_MAX_BUF_LEN_WORDS) { + rtp_session->recv_msg.ebody = rtp_session->recv_msg.body + (length * 4) + 4; } } From 54ae6ff6c175d913298f49f1498002f264068906 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Fri, 1 Nov 2013 10:32:32 +0800 Subject: [PATCH 024/656] Adjusted the test for -Wunused-but-set-variable in spandsp, so it gets the answer right with clang. --- libs/spandsp/configure.ac | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libs/spandsp/configure.ac b/libs/spandsp/configure.ac index de395ec4cc..423513100c 100644 --- a/libs/spandsp/configure.ac +++ b/libs/spandsp/configure.ac @@ -324,9 +324,11 @@ AX_CHECK_EXPORT_CAPABILITY([$host], saved_CFLAGS="$CFLAGS" AC_CACHE_CHECK([whether compiler supports -Wunused-but-set-variable], [ac_cv_gcc_unused_but_set_variable], [ -CFLAGS="$CFLAGS -Wunused-but-set-variable" -AC_TRY_COMPILE([],[return 0;],[ac_cv_gcc_unused_but_set_variable=yes],[ac_cv_gcc_unused_but_set_variable=no]) -]) + # We need to add -Werror here or clang doesn't fail (it just warns), even though it doesn't understand the + # -Wunused-but-set-variable tag + CFLAGS="$CFLAGS -Werror -Wunused-but-set-variable" + AC_TRY_COMPILE([],[return 0;],[ac_cv_gcc_unused_but_set_variable=yes],[ac_cv_gcc_unused_but_set_variable=no]) + ]) AC_MSG_RESULT($ac_cv_gcc_unused_but_set_variable) CFLAGS="$saved_CFLAGS" From 2589bf7750a2e1e715d7d1bbc6ce62ee43b41c54 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 2 Nov 2013 01:21:35 +0500 Subject: [PATCH 025/656] minor webrtc tweaks --- .../mod_conference/mod_conference.c | 2 +- src/switch_rtp.c | 54 +++++++++++++++++-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 61a50854ea..8f3f1a81b8 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1915,7 +1915,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe if (conference->la && member->channel) { member->json = cJSON_CreateArray(); - cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%0.8d", member->id)); + cJSON_AddItemToArray(member->json, cJSON_CreateStringPrintf("%0.4d", member->id)); cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_number"))); cJSON_AddItemToArray(member->json, cJSON_CreateString(switch_channel_get_variable(member->channel, "caller_id_name"))); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 325a41fd07..4d644adf0c 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2511,12 +2511,42 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, d if (rtp_session->dtls) { free_dtls(&rtp_session->dtls); } + + if (rtp_session->jb) { + stfu_n_reset(rtp_session->jb); + } + } if ((type & DTLS_TYPE_RTCP) && rtp_session->rtcp_dtls) { free_dtls(&rtp_session->rtcp_dtls); } + +#ifdef ENABLE_SRTP + if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND]) { + int x; + for(x = 0; x < 2; x++) { + if (rtp_session->send_ctx[x]) { + srtp_dealloc(rtp_session->send_ctx[x]); + rtp_session->send_ctx[x] = NULL; + } + } + rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] = 0; + } + + if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV]) { + int x; + for (x = 0; x < 2; x++) { + if (rtp_session->recv_ctx[x]) { + srtp_dealloc(rtp_session->recv_ctx[x]); + rtp_session->recv_ctx[x] = NULL; + } + } + rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] = 0; + } +#endif + return SWITCH_STATUS_SUCCESS; } @@ -3363,7 +3393,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio ice->ice_params = ice_params; ice->pass = ""; ice->rpass = ""; - + ice->ready = 0; + ice->rready = 0; ice->next_run = switch_micro_time_now(); if (password) { @@ -4017,6 +4048,21 @@ static void do_flush(switch_rtp_t *rtp_session, int force) READ_DEC(rtp_session); } +static int jb_valid(switch_rtp_t *rtp_session) +{ + if (rtp_session->ice.ice_user) { + if (!rtp_session->ice.ready && rtp_session->ice.rready) { + return 0; + } + } + + if (rtp_session->dtls && rtp_session->dtls->state != DS_READY) { + return 0; + } + + return 1; +} + #define return_cng_frame() do_cng = 1; goto timer_check static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes, switch_frame_flag_t *flags, switch_bool_t return_jb_packet) @@ -4224,7 +4270,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (!rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && !rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && *bytes && (!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) && - ts && !rtp_session->jb && !rtp_session->pause_jb && ts == rtp_session->last_cng_ts) { + ts && !rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session) && ts == rtp_session->last_cng_ts) { /* we already sent this frame..... */ *bytes = 0; return SWITCH_STATUS_SUCCESS; @@ -4342,7 +4388,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t } - if (rtp_session->jb && !rtp_session->pause_jb && rtp_session->recv_msg.header.version == 2 && *bytes) { + if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session) && rtp_session->recv_msg.header.version == 2 && *bytes) { if (rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) { stfu_n_reset(rtp_session->jb); @@ -4367,7 +4413,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes = 0; } - if (rtp_session->jb && !rtp_session->pause_jb) { + if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) { if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) { memcpy(RTP_BODY(rtp_session), jb_frame->data, jb_frame->dlen); From b86770f34c7935ab172040f7938d8260242a1c28 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 1 Nov 2013 16:33:41 -0500 Subject: [PATCH 026/656] FS-5935 --resolve this was broken from the initial check in FS-5524 --- src/mod/languages/mod_lua/mod_lua.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mod/languages/mod_lua/mod_lua.cpp b/src/mod/languages/mod_lua/mod_lua.cpp index a21643bc97..9715f0dc74 100644 --- a/src/mod/languages/mod_lua/mod_lua.cpp +++ b/src/mod/languages/mod_lua/mod_lua.cpp @@ -45,7 +45,6 @@ SWITCH_MODULE_DEFINITION_EX(mod_lua, mod_lua_load, mod_lua_shutdown, NULL, SMODF static struct { switch_memory_pool_t *pool; char *xml_handler; - switch_event_node_t *node; } globals; int luaopen_freeswitch(lua_State * L); @@ -339,12 +338,16 @@ static switch_status_t do_config(void) char *script = (char *) switch_xml_attr_soft(hook, "script"); switch_event_types_t evtype; + if (!zstr(script)) { + script = switch_core_strdup(globals.pool, script); + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "hook params: '%s' | '%s' | '%s'\n", event, subclass, script); if (switch_name_event(event,&evtype) == SWITCH_STATUS_SUCCESS) { if (!zstr(script)) { - if (switch_event_bind_removable(modname, evtype, !zstr(subclass) ? subclass : SWITCH_EVENT_SUBCLASS_ANY, - lua_event_handler, script, &globals.node) == SWITCH_STATUS_SUCCESS) { + if (switch_event_bind(modname, evtype, !zstr(subclass) ? subclass : SWITCH_EVENT_SUBCLASS_ANY, + lua_event_handler, script) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event handler for '%s' set to '%s'\n", switch_event_name(evtype), script); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot set event handler: unsuccessful bind\n"); @@ -691,7 +694,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_lua_shutdown) { - switch_event_unbind(&globals.node); + switch_event_unbind_callback(lua_event_handler); return SWITCH_STATUS_SUCCESS; } From 859afe9429d37d6fb759dfbd0a9861498d80cb59 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 2 Nov 2013 10:31:23 -0500 Subject: [PATCH 027/656] FS-5930 --resolve --- src/mod/formats/mod_local_stream/mod_local_stream.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index bae5408014..a96d01c4c3 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -311,20 +311,20 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void if (!is_open || used >= source->prebuf || (source->total && used > source->samples * 2)) { used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2); if (source->total) { - uint32_t used = 0; + uint32_t bused = 0; switch_mutex_lock(source->mutex); for (cp = source->context_list; cp && RUNNING; cp = cp->next) { if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) { continue; } switch_mutex_lock(cp->audio_mutex); - used = switch_buffer_inuse(cp->audio_buffer); - if (used > source->samples * 768) { + bused = switch_buffer_inuse(cp->audio_buffer); + if (bused > source->samples * 768) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Flushing Stream Handle Buffer [%s() %s:%d] size: %u samples: %ld\n", - cp->func, cp->file, cp->line, used, (long)source->samples); + cp->func, cp->file, cp->line, bused, (long)source->samples); switch_buffer_zero(cp->audio_buffer); } else { - switch_buffer_write(cp->audio_buffer, dist_buf, used); + switch_buffer_write(cp->audio_buffer, dist_buf, bused); } switch_mutex_unlock(cp->audio_mutex); } From ad8796f58160ce7154530483a9abd196d917b209 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Sat, 2 Nov 2013 17:34:16 -0500 Subject: [PATCH 028/656] FS-5930 --resolve --- src/mod/formats/mod_local_stream/mod_local_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index a96d01c4c3..c94958ea87 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -324,7 +324,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void cp->func, cp->file, cp->line, bused, (long)source->samples); switch_buffer_zero(cp->audio_buffer); } else { - switch_buffer_write(cp->audio_buffer, dist_buf, bused); + switch_buffer_write(cp->audio_buffer, dist_buf, used); } switch_mutex_unlock(cp->audio_mutex); } From 381caad87f1d10f8408f573892bb01bdea242fd6 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 4 Nov 2013 14:28:07 -0500 Subject: [PATCH 029/656] FS-5921 --resolve mod_mongo: use jsonString() instead of toString(), tabs instead of spaces --- src/mod/applications/mod_mongo/mod_mongo.cpp | 100 ++++----- src/mod/applications/mod_mongo/mod_mongo.h | 20 +- src/mod/applications/mod_mongo/mongo_conn.cpp | 195 +++++++++--------- 3 files changed, 157 insertions(+), 158 deletions(-) diff --git a/src/mod/applications/mod_mongo/mod_mongo.cpp b/src/mod/applications/mod_mongo/mod_mongo.cpp index 83b31c7546..811361be21 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.cpp +++ b/src/mod/applications/mod_mongo/mod_mongo.cpp @@ -1,6 +1,6 @@ -/* +/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II + * Copyright (C) 2005-2013, Anthony Minessale II * * Version: MPL 1.1 * @@ -22,7 +22,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * + * * Tamas Cseke * * mod_mongo.cpp -- API for MongoDB @@ -53,7 +53,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function) switch_assert(ns != NULL); if ((json_query = strchr(ns, DELIMITER))) { - *json_query++ = '\0'; + *json_query++ = '\0'; } if (!zstr(ns) && !zstr(json_query)) { @@ -82,7 +82,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function) conn->runCommand(conn->nsGetDB(ns), cmd.done(), out); mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE); - stream->write_function(stream, "-OK\n%s\n", out.toString().c_str()); + stream->write_function(stream, "-OK\n%s\n", out.jsonString().c_str()); } else { stream->write_function(stream, "-ERR\nNo connection\n"); } @@ -93,7 +93,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function) stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str()); } } else { - stream->write_function(stream, "-ERR\n%s\n", MAPREDUCE_SYNTAX); + stream->write_function(stream, "-ERR\n%s\n", MAPREDUCE_SYNTAX); } switch_safe_free(ns); @@ -104,50 +104,50 @@ SWITCH_STANDARD_API(mongo_mapreduce_function) SWITCH_STANDARD_API(mongo_find_one_function) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - char *ns = NULL, *json_query = NULL, *json_fields = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + char *ns = NULL, *json_query = NULL, *json_fields = NULL; - ns = strdup(cmd); - switch_assert(ns != NULL); + ns = strdup(cmd); + switch_assert(ns != NULL); - if ((json_query = strchr(ns, DELIMITER))) { - *json_query++ = '\0'; - if ((json_fields = strchr(json_query, DELIMITER))) { - *json_fields++ = '\0'; - } - } + if ((json_query = strchr(ns, DELIMITER))) { + *json_query++ = '\0'; + if ((json_fields = strchr(json_query, DELIMITER))) { + *json_fields++ = '\0'; + } + } - if (!zstr(ns) && !zstr(json_query) && !zstr(json_fields)) { + if (!zstr(ns) && !zstr(json_query) && !zstr(json_fields)) { - DBClientBase *conn = NULL; + DBClientBase *conn = NULL; - try { - BSONObj query = fromjson(json_query); - BSONObj fields = fromjson(json_fields); + try { + BSONObj query = fromjson(json_query); + BSONObj fields = fromjson(json_fields); - conn = mongo_connection_pool_get(globals.conn_pool); - if (conn) { - BSONObj res = conn->findOne(ns, Query(query), &fields); - mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE); + conn = mongo_connection_pool_get(globals.conn_pool); + if (conn) { + BSONObj res = conn->findOne(ns, Query(query), &fields); + mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE); - stream->write_function(stream, "-OK\n%s\n", res.toString().c_str()); - } else { - stream->write_function(stream, "-ERR\nNo connection\n"); - } - } catch (DBException &e) { - if (conn) { - mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_TRUE); - } - stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str()); - } + stream->write_function(stream, "-OK\n%s\n", res.jsonString().c_str()); + } else { + stream->write_function(stream, "-ERR\nNo connection\n"); + } + } catch (DBException &e) { + if (conn) { + mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_TRUE); + } + stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str()); + } - } else { + } else { stream->write_function(stream, "-ERR\n%s\n", FIND_ONE_SYNTAX); - } + } - switch_safe_free(ns); + switch_safe_free(ns); - return status; + return status; } static switch_status_t config(void) @@ -214,21 +214,21 @@ SWITCH_MODULE_DEFINITION(mod_mongo, mod_mongo_load, mod_mongo_shutdown, NULL); SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load) { - switch_api_interface_t *api_interface; - switch_application_interface_t *app_interface; + switch_api_interface_t *api_interface; + switch_application_interface_t *app_interface; - *module_interface = switch_loadable_module_create_module_interface(pool, modname); + *module_interface = switch_loadable_module_create_module_interface(pool, modname); - memset(&globals, 0, sizeof(globals)); + memset(&globals, 0, sizeof(globals)); - if (config() != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_TERM; - } - - SWITCH_ADD_API(api_interface, "mongo_find_one", "findOne", mongo_find_one_function, FIND_ONE_SYNTAX); - SWITCH_ADD_API(api_interface, "mongo_mapreduce", "Map/Reduce", mongo_mapreduce_function, MAPREDUCE_SYNTAX); + if (config() != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_TERM; + } - return SWITCH_STATUS_SUCCESS; + SWITCH_ADD_API(api_interface, "mongo_find_one", "findOne", mongo_find_one_function, FIND_ONE_SYNTAX); + SWITCH_ADD_API(api_interface, "mongo_mapreduce", "Map/Reduce", mongo_mapreduce_function, MAPREDUCE_SYNTAX); + + return SWITCH_STATUS_SUCCESS; } SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown) diff --git a/src/mod/applications/mod_mongo/mod_mongo.h b/src/mod/applications/mod_mongo/mod_mongo.h index 00e927f3a1..df09434352 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.h +++ b/src/mod/applications/mod_mongo/mod_mongo.h @@ -1,6 +1,6 @@ -/* +/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II + * Copyright (C) 2005-2013, Anthony Minessale II * * Version: MPL 1.1 * @@ -40,14 +40,14 @@ using namespace mongo; typedef struct { - char *conn_str; + char *conn_str; - switch_size_t min_connections; - switch_size_t max_connections; - switch_size_t size; - switch_queue_t *connections; - switch_mutex_t *mutex; - switch_memory_pool_t *pool; + switch_size_t min_connections; + switch_size_t max_connections; + switch_size_t size; + switch_queue_t *connections; + switch_mutex_t *mutex; + switch_memory_pool_t *pool; } mongo_connection_pool_t; @@ -56,7 +56,7 @@ switch_status_t mongo_connection_create(DBClientBase **connection, const char *c void mongo_connection_destroy(DBClientBase **conn); switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections, - const char *conn_str); + const char *conn_str); void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool); diff --git a/src/mod/applications/mod_mongo/mongo_conn.cpp b/src/mod/applications/mod_mongo/mongo_conn.cpp index 8c7687b860..fd095fe54a 100644 --- a/src/mod/applications/mod_mongo/mongo_conn.cpp +++ b/src/mod/applications/mod_mongo/mongo_conn.cpp @@ -1,6 +1,6 @@ /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2012, Anthony Minessale II + * Copyright (C) 2005-2013, Anthony Minessale II * * Version: MPL 1.1 * @@ -42,162 +42,161 @@ switch_status_t mongo_connection_create(DBClientBase **connection, const char *conn_str) { - DBClientBase *conn = NULL; - string conn_string(conn_str), err_msg; - ConnectionString cs = ConnectionString::parse(conn_string, err_msg); - switch_status_t status = SWITCH_STATUS_FALSE; - - if (!cs.isValid()) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't parse url: %s\n", err_msg.c_str()); - return status; - } + DBClientBase *conn = NULL; + string conn_string(conn_str), err_msg; + ConnectionString cs = ConnectionString::parse(conn_string, err_msg); + switch_status_t status = SWITCH_STATUS_FALSE; - try { - conn = cs.connect(err_msg); - } catch (DBException &e) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]: %s\n", conn_str, err_msg.c_str()); - return status; - } + if (!cs.isValid()) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't parse url: %s\n", err_msg.c_str()); + return status; + } - if (conn) { - *connection = conn; - status = SWITCH_STATUS_SUCCESS; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", conn_str); - } + try { + conn = cs.connect(err_msg); + } catch (DBException &e) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]: %s\n", conn_str, err_msg.c_str()); + return status; + } - return status; + if (conn) { + *connection = conn; + status = SWITCH_STATUS_SUCCESS; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", conn_str); + } + + return status; } void mongo_connection_destroy(DBClientBase **conn) { - switch_assert(*conn != NULL); - delete *conn; + switch_assert(*conn != NULL); + delete *conn; - *conn = NULL; + *conn = NULL; } switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections, - const char *conn_str) + const char *conn_str) { - switch_memory_pool_t *pool = NULL; - switch_status_t status = SWITCH_STATUS_SUCCESS; - mongo_connection_pool_t *cpool = NULL; - DBClientBase *conn = NULL; + switch_memory_pool_t *pool = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + mongo_connection_pool_t *cpool = NULL; + DBClientBase *conn = NULL; - if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) { - return status; - } + if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) { + return status; + } - if (!(cpool = (mongo_connection_pool_t *)switch_core_alloc(pool, sizeof(mongo_connection_pool_t)))) { - switch_goto_status(SWITCH_STATUS_MEMERR, done); - } + if (!(cpool = (mongo_connection_pool_t *)switch_core_alloc(pool, sizeof(mongo_connection_pool_t)))) { + switch_goto_status(SWITCH_STATUS_MEMERR, done); + } - if ((status = switch_mutex_init(&cpool->mutex, SWITCH_MUTEX_NESTED, pool)) != SWITCH_STATUS_SUCCESS) { - goto done; - } + if ((status = switch_mutex_init(&cpool->mutex, SWITCH_MUTEX_NESTED, pool)) != SWITCH_STATUS_SUCCESS) { + goto done; + } - if ((status = switch_queue_create(&cpool->connections, max_connections, pool)) != SWITCH_STATUS_SUCCESS) { - goto done; - } + if ((status = switch_queue_create(&cpool->connections, max_connections, pool)) != SWITCH_STATUS_SUCCESS) { + goto done; + } - cpool->min_connections = min_connections; - cpool->max_connections = max_connections; - cpool->conn_str = switch_core_strdup(pool, conn_str); - - cpool->pool = pool; + cpool->min_connections = min_connections; + cpool->max_connections = max_connections; + cpool->conn_str = switch_core_strdup(pool, conn_str); + cpool->pool = pool; - for (cpool->size = 0; cpool->size < min_connections; cpool->size++) { + for (cpool->size = 0; cpool->size < min_connections; cpool->size++) { - if (mongo_connection_create(&conn, conn_str) == SWITCH_STATUS_SUCCESS) { - mongo_connection_pool_put(cpool, conn, SWITCH_FALSE); - } else { - break; - } - } + if (mongo_connection_create(&conn, conn_str) == SWITCH_STATUS_SUCCESS) { + mongo_connection_pool_put(cpool, conn, SWITCH_FALSE); + } else { + break; + } + } done: - if (status == SWITCH_STATUS_SUCCESS) { - *conn_pool = cpool; - } else { - switch_core_destroy_memory_pool(&pool); - } + if (status == SWITCH_STATUS_SUCCESS) { + *conn_pool = cpool; + } else { + switch_core_destroy_memory_pool(&pool); + } - return status; + return status; } void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool) { - mongo_connection_pool_t *cpool = *conn_pool; - void *data = NULL; + mongo_connection_pool_t *cpool = *conn_pool; + void *data = NULL; - switch_assert(cpool != NULL); + switch_assert(cpool != NULL); - while (switch_queue_trypop(cpool->connections, &data) == SWITCH_STATUS_SUCCESS) { - mongo_connection_destroy((DBClientBase **)&data); - } + while (switch_queue_trypop(cpool->connections, &data) == SWITCH_STATUS_SUCCESS) { + mongo_connection_destroy((DBClientBase **)&data); + } - switch_mutex_destroy(cpool->mutex); - switch_core_destroy_memory_pool(&cpool->pool); + switch_mutex_destroy(cpool->mutex); + switch_core_destroy_memory_pool(&cpool->pool); - *conn_pool = NULL; + *conn_pool = NULL; } DBClientBase *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool) { - DBClientBase *conn = NULL; - void *data = NULL; + DBClientBase *conn = NULL; + void *data = NULL; - switch_assert(conn_pool != NULL); + switch_assert(conn_pool != NULL); - switch_mutex_lock(conn_pool->mutex); + switch_mutex_lock(conn_pool->mutex); - if (switch_queue_trypop(conn_pool->connections, &data) == SWITCH_STATUS_SUCCESS) { - conn = (DBClientBase *) data; - } else if (mongo_connection_create(&conn, conn_pool->conn_str) == SWITCH_STATUS_SUCCESS) { - if (++conn_pool->size > conn_pool->max_connections) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Connection pool is empty. You may want to increase 'max-connections'\n"); - } - } + if (switch_queue_trypop(conn_pool->connections, &data) == SWITCH_STATUS_SUCCESS) { + conn = (DBClientBase *) data; + } else if (mongo_connection_create(&conn, conn_pool->conn_str) == SWITCH_STATUS_SUCCESS) { + if (++conn_pool->size > conn_pool->max_connections) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Connection pool is empty. You may want to increase 'max-connections'\n"); + } + } - switch_mutex_unlock(conn_pool->mutex); + switch_mutex_unlock(conn_pool->mutex); #ifdef MONGO_POOL_DEBUG - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL get: size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL get: size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn); #endif - return conn; + return conn; } switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientBase *conn, switch_bool_t destroy) { - switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_assert(conn_pool != NULL); - switch_assert(conn != NULL); + switch_assert(conn_pool != NULL); + switch_assert(conn != NULL); - switch_mutex_lock(conn_pool->mutex); - if (destroy || conn_pool->size > conn_pool->max_connections) { + switch_mutex_lock(conn_pool->mutex); + if (destroy || conn_pool->size > conn_pool->max_connections) { #ifdef MONGO_POOL_DEBUG - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: Destroy connection %p\n", conn); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: Destroy connection %p\n", conn); #endif - mongo_connection_destroy(&conn); - conn_pool->size--; - } else { + mongo_connection_destroy(&conn); + conn_pool->size--; + } else { #ifdef MONGO_POOL_DEBUG - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: push connection %p\n", conn); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: push connection %p\n", conn); #endif - status = switch_queue_push(conn_pool->connections, conn); - } + status = switch_queue_push(conn_pool->connections, conn); + } - switch_mutex_unlock(conn_pool->mutex); + switch_mutex_unlock(conn_pool->mutex); #ifdef MONGO_POOL_DEBUG - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: put size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: put size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn); #endif - return status; + return status; } /* For Emacs: From 384ddf1517be4a3b9080a3ed8667a63156073144 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 4 Nov 2013 14:29:48 -0500 Subject: [PATCH 030/656] FS-5931 --resolve mod_mongo: update driver to v2.4 --- src/mod/applications/mod_mongo/Makefile | 4 ++-- src/mod/applications/mod_mongo/fpic_hack.diff | 16 ++++++++-------- src/mod/applications/mod_mongo/mod_mongo.cpp | 4 ++-- src/mod/applications/mod_mongo/mod_mongo.h | 5 +---- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/mod/applications/mod_mongo/Makefile b/src/mod/applications/mod_mongo/Makefile index 9ce16b1171..7a6e1058ab 100644 --- a/src/mod/applications/mod_mongo/Makefile +++ b/src/mod/applications/mod_mongo/Makefile @@ -1,6 +1,6 @@ BASE=../../../.. -MONGO_CXX_DRIVER_VERSION=v1.8 +MONGO_CXX_DRIVER_VERSION=v2.4 MONGO_CXX_DRIVER_URL=http://downloads.mongodb.org/cxx-driver MONGO_CXX_DRIVER_TARBALL=mongodb-linux-x86_64-$(MONGO_CXX_DRIVER_VERSION)-latest.tgz MONGO_CXX_DRIVER_SRC=$(BASE)/libs/mongo-cxx-driver-$(MONGO_CXX_DRIVER_VERSION) @@ -9,7 +9,7 @@ LIBMONGOCLIENT_A =$(MONGO_CXX_DRIVER_SRC)/libmongoclient.a LOCAL_SOURCES=mongo_conn.cpp LOCAL_OBJS=mongo_conn.o -LOCAL_CFLAGS=-I$(MONGO_CXX_DRIVER_SRC)/mongo +LOCAL_CFLAGS=-I$(MONGO_CXX_DRIVER_SRC)/src LOCAL_LIBADD=$(LIBMONGOCLIENT_A) LOCAL_LDFLAGS=-lboost_thread -lboost_filesystem-mt -lboost_system-mt MODDIR=$(shell pwd) diff --git a/src/mod/applications/mod_mongo/fpic_hack.diff b/src/mod/applications/mod_mongo/fpic_hack.diff index 882f3c899a..1f85f85c97 100644 --- a/src/mod/applications/mod_mongo/fpic_hack.diff +++ b/src/mod/applications/mod_mongo/fpic_hack.diff @@ -1,11 +1,11 @@ ---- SConstruct.orig 2011-04-28 19:00:36.000000000 +0200 -+++ SConstruct 2011-04-28 19:01:19.000000000 +0200 -@@ -45,7 +45,7 @@ - linux = True +--- SConstruct 2013-10-30 17:18:51.160645496 -0400 ++++ new 2013-10-30 17:22:18.790072856 -0400 +@@ -78,7 +78,7 @@ + env['DIST_ARCHIVE_SUFFIX'] = '.tgz' if nix: -- env.Append( CPPFLAGS=" -O3" ) -+ env.Append( CPPFLAGS=" -I../pcre -fPIC -O3" ) - env.Append( LIBS=["pthread"] ) +- env.Append(CCFLAGS=["-O3", "-pthread"]) ++ env.Append(CCFLAGS=["-I../pcre", "-fPIC", "-O3", "-pthread"]) if linux: - env.Append( LINKFLAGS=" -Wl,--as-needed -Wl,-zdefs " ) + env.Append(LINKFLAGS=["-pthread"]) + diff --git a/src/mod/applications/mod_mongo/mod_mongo.cpp b/src/mod/applications/mod_mongo/mod_mongo.cpp index 811361be21..8c3536def2 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.cpp +++ b/src/mod/applications/mod_mongo/mod_mongo.cpp @@ -62,7 +62,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function) BSONObj out; BSONObjBuilder cmd; - cmd.append("mapreduce", conn->nsGetCollection(ns)); + cmd.append("mapreduce", nsGetCollection(ns)); if (!zstr(globals.map)) { cmd.appendCode("map", globals.map); } @@ -79,7 +79,7 @@ SWITCH_STANDARD_API(mongo_mapreduce_function) conn = mongo_connection_pool_get(globals.conn_pool); if (conn) { - conn->runCommand(conn->nsGetDB(ns), cmd.done(), out); + conn->runCommand(nsGetDB(ns), cmd.done(), out); mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE); stream->write_function(stream, "-OK\n%s\n", out.jsonString().c_str()); diff --git a/src/mod/applications/mod_mongo/mod_mongo.h b/src/mod/applications/mod_mongo/mod_mongo.h index df09434352..822dacaf63 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.h +++ b/src/mod/applications/mod_mongo/mod_mongo.h @@ -32,10 +32,7 @@ #ifndef MOD_MONGO_H #define MOD_MONGO_H -#include -#include -#include -#include +#include using namespace mongo; From 90f0fdb93d50073b808d71eff40af5e1fafbf96b Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 5 Nov 2013 15:15:49 -0500 Subject: [PATCH 031/656] mod_rayo: default record format is now wav --- src/mod/event_handlers/mod_rayo/rayo_elements.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.c b/src/mod/event_handlers/mod_rayo/rayo_elements.c index 34577a9492..2bbf701794 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.c +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.c @@ -80,7 +80,7 @@ ELEMENT_END * component validation */ ELEMENT(RAYO_RECORD) - ATTRIB(format, mp3, any) + ATTRIB(format, wav, any) ATTRIB(start-beep, false, bool) ATTRIB(stop-beep, false, bool) ATTRIB(start-paused, false, bool) From bb5d283e501bb9425d381cc17f0127d69282fbcc Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 6 Nov 2013 17:00:13 -0500 Subject: [PATCH 032/656] mod_rayo: component added. No support for HTTP(S) yet. --- conf/rayo/autoload_configs/rayo.conf.xml | 7 + src/mod/event_handlers/mod_rayo/Makefile | 2 + .../conf/autoload_configs/rayo.conf.xml | 7 + src/mod/event_handlers/mod_rayo/mod_rayo.c | 50 ++- src/mod/event_handlers/mod_rayo/mod_rayo.h | 3 + .../event_handlers/mod_rayo/rayo_components.c | 4 +- .../event_handlers/mod_rayo/rayo_components.h | 5 + .../event_handlers/mod_rayo/rayo_elements.c | 12 + .../event_handlers/mod_rayo/rayo_elements.h | 1 + .../mod_rayo/rayo_receivefax_component.c | 378 ++++++++++++++++++ 10 files changed, 464 insertions(+), 5 deletions(-) create mode 100644 src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index 35419319bc..c8171569af 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -16,6 +16,12 @@ + + + + + + @@ -65,6 +71,7 @@ ]]> ]]> ]]> + ]]> ]]> ]]> ]]> diff --git a/src/mod/event_handlers/mod_rayo/Makefile b/src/mod/event_handlers/mod_rayo/Makefile index 6fccfdf318..bfb38dbd6c 100644 --- a/src/mod/event_handlers/mod_rayo/Makefile +++ b/src/mod/event_handlers/mod_rayo/Makefile @@ -14,6 +14,7 @@ LOCAL_OBJS= $(IKS_LA) \ rayo_input_component.o \ rayo_output_component.o \ rayo_prompt_component.o \ + rayo_receivefax_component.o \ rayo_record_component.o \ sasl.o \ srgs.o \ @@ -27,6 +28,7 @@ LOCAL_SOURCES= \ rayo_output_component.c \ rayo_prompt_component.c \ rayo_record_component.c \ + rayo_receivefax_component.c \ sasl.c \ srgs.c \ xmpp_streams.c diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index 35419319bc..c8171569af 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -16,6 +16,12 @@ + + + + + + @@ -65,6 +71,7 @@ ]]> ]]> ]]> + ]]> ]]> ]]> ]]> diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 6dd58d29c6..c5a57eeda5 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -126,6 +126,8 @@ struct rayo_call { switch_hash_t *pcps; /** current idle start time */ switch_time_t idle_start_time; + /** true if fax is in progress */ + int faxing; /** 1 if joined to call, 2 if joined to mixer */ int joined; /** pending join */ @@ -963,11 +965,35 @@ const char *rayo_call_get_dcp_jid(struct rayo_call *call) /** * @param call the Rayo call - * @return true if joined + * @return true if joined (or a join is in progress) */ -static int rayo_call_is_joined(struct rayo_call *call) +int rayo_call_is_joined(struct rayo_call *call) { - return call->joined; + return call->joined || call->pending_join_request; +} + +/** + * @param call to check if faxing + * @return true if faxing is in progress + */ +int rayo_call_is_faxing(struct rayo_call *call) +{ + return call->faxing; +} + +/** + * Set faxing flag if faxing is not in progress + * @param call the call to flag + * @param faxing true if faxing is in progress + * @return true if set, false if can't set because faxing is already in progress. Reset always succeeds. + */ +int rayo_call_set_faxing(struct rayo_call *call, int faxing) +{ + if (!faxing || (faxing && !call->faxing)) { + call->faxing = faxing; + return 1; + } + return 0; } #define RAYO_MIXER_LOCATE(mixer_name) rayo_mixer_locate(mixer_name, __FILE__, __LINE__) @@ -1942,6 +1968,12 @@ static iks *on_rayo_join(struct rayo_actor *call, struct rayo_message *msg, void goto done; } + if (rayo_call_is_faxing(RAYO_CALL(call))) { + /* can't join a call while it's faxing */ + response = iks_new_error_detailed(msg->payload, STANZA_ERROR_UNEXPECTED_REQUEST, "fax is in progress"); + goto done; + } + if (RAYO_CALL(call)->pending_join_request) { /* don't allow concurrent join requests */ response = iks_new_error_detailed(msg->payload, STANZA_ERROR_UNEXPECTED_REQUEST, "(un)join request is pending"); @@ -3074,12 +3106,22 @@ static switch_status_t rayo_call_on_read_frame(switch_core_session_t *session, s switch_time_t idle_start = call->idle_start_time; int idle_duration_ms = (now - idle_start) / 1000; /* detect idle session (rayo-client has stopped controlling call) and terminate call */ - if (rayo_call_is_joined(call)) { + if (rayo_call_is_joined(call) || rayo_call_is_faxing(call)) { call->idle_start_time = now; } else if (idle_duration_ms > globals.max_idle_ms) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Ending abandoned call. idle_duration_ms = %i ms\n", idle_duration_ms); switch_channel_hangup(channel, RAYO_CAUSE_HANGUP); } + + /* check for break request */ + { + const char *break_jid = switch_channel_get_variable(channel, "rayo_read_frame_interrupt"); + struct rayo_actor *actor; + if (break_jid && (actor = RAYO_LOCATE(break_jid))) { + RAYO_UNLOCK(actor); + return SWITCH_STATUS_FALSE; + } + } } return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.h b/src/mod/event_handlers/mod_rayo/mod_rayo.h index dd0adb3192..c65236b64a 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.h +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.h @@ -153,6 +153,9 @@ extern void rayo_actor_destroy(struct rayo_actor *actor, const char *file, int l #define RAYO_DESTROY(x) rayo_actor_destroy(RAYO_ACTOR(x), __FILE__, __LINE__) #define RAYO_SEQ_NEXT(x) rayo_actor_seq_next(RAYO_ACTOR(x)) +extern int rayo_call_is_joined(struct rayo_call *call); +extern int rayo_call_is_faxing(struct rayo_call *call); +extern int rayo_call_set_faxing(struct rayo_call *call, int faxing); extern const char *rayo_call_get_dcp_jid(struct rayo_call *call); #define rayo_mixer_get_name(mixer) RAYO_ID(mixer) diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c index b5137d9459..2448e166a8 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_components.c @@ -226,7 +226,8 @@ switch_status_t rayo_components_load(switch_loadable_module_interface_t **module if (rayo_input_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || rayo_output_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || rayo_prompt_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_record_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { + rayo_record_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || + rayo_receivefax_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_TERM; } return SWITCH_STATUS_SUCCESS; @@ -241,6 +242,7 @@ switch_status_t rayo_components_shutdown(void) rayo_output_component_shutdown(); rayo_prompt_component_shutdown(); rayo_record_component_shutdown(); + rayo_receivefax_component_shutdown(); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.h b/src/mod/event_handlers/mod_rayo/rayo_components.h index 6e93dfbc43..8d3909dd4d 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.h +++ b/src/mod/event_handlers/mod_rayo/rayo_components.h @@ -49,6 +49,9 @@ #define RAYO_PROMPT_NS RAYO_BASE "prompt:" RAYO_VERSION #define RAYO_PROMPT_COMPLETE_NS RAYO_BASE "prompt:complete:" RAYO_VERSION +#define RAYO_FAX_NS RAYO_BASE "fax:" RAYO_VERSION +#define RAYO_FAX_COMPLETE_NS RAYO_BASE "fax:complete:" RAYO_VERSION + #define COMPONENT_COMPLETE_STOP "stop", RAYO_EXT_COMPLETE_NS #define COMPONENT_COMPLETE_ERROR "error", RAYO_EXT_COMPLETE_NS #define COMPONENT_COMPLETE_HANGUP "hangup", RAYO_EXT_COMPLETE_NS @@ -58,12 +61,14 @@ extern switch_status_t rayo_input_component_load(switch_loadable_module_interfac extern switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_components_shutdown(void); extern switch_status_t rayo_input_component_shutdown(void); extern switch_status_t rayo_output_component_shutdown(void); extern switch_status_t rayo_prompt_component_shutdown(void); extern switch_status_t rayo_record_component_shutdown(void); +extern switch_status_t rayo_receivefax_component_shutdown(void); extern void rayo_component_send_start(struct rayo_component *component, iks *iq); extern void rayo_component_send_iq_error(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type); diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.c b/src/mod/event_handlers/mod_rayo/rayo_elements.c index 2bbf701794..a6e4f09140 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.c +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.c @@ -32,6 +32,7 @@ * component validation */ ELEMENT(RAYO_INPUT) + ATTRIB(xmlns,, any) STRING_ATTRIB(mode, any, "any,dtmf,voice") OPTIONAL_ATTRIB(terminator,, dtmf_digit) ATTRIB(recognizer,, any) @@ -52,6 +53,7 @@ ELEMENT_END * component validation */ ELEMENT(RAYO_OUTPUT) + ATTRIB(xmlns,, any) ATTRIB(start-offset, 0, not_negative) ATTRIB(start-paused, false, bool) ATTRIB(repeat-interval, 0, not_negative) @@ -65,6 +67,7 @@ ELEMENT_END * validation */ ELEMENT(RAYO_OUTPUT_SEEK) + ATTRIB(xmlns,, any) STRING_ATTRIB(direction,, "forward,back") ATTRIB(amount,-1, positive) ELEMENT_END @@ -73,6 +76,7 @@ ELEMENT_END * component validation */ ELEMENT(RAYO_PROMPT) + ATTRIB(xmlns,, any) ATTRIB(barge-in, true, bool) ELEMENT_END @@ -80,6 +84,7 @@ ELEMENT_END * component validation */ ELEMENT(RAYO_RECORD) + ATTRIB(xmlns,, any) ATTRIB(format, wav, any) ATTRIB(start-beep, false, bool) ATTRIB(stop-beep, false, bool) @@ -95,12 +100,19 @@ ELEMENT_END * command validation */ ELEMENT(RAYO_JOIN) + ATTRIB(xmlns,, any) STRING_ATTRIB(direction, duplex, "send,recv,duplex") STRING_ATTRIB(media, bridge, "bridge,direct") ATTRIB(call-uri,, any) ATTRIB(mixer-name,, any) ELEMENT_END +/** + * command validation + */ +ELEMENT(RAYO_RECEIVEFAX) + ATTRIB(xmlns,, any) +ELEMENT_END /* For Emacs: * Local Variables: diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.h b/src/mod/event_handlers/mod_rayo/rayo_elements.h index c780f160cf..4c061dc35e 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.h +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.h @@ -37,6 +37,7 @@ ELEMENT_DECL(RAYO_OUTPUT_SEEK) ELEMENT_DECL(RAYO_PROMPT) ELEMENT_DECL(RAYO_RECORD) ELEMENT_DECL(RAYO_JOIN) +ELEMENT_DECL(RAYO_RECEIVEFAX) #endif diff --git a/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c b/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c new file mode 100644 index 0000000000..09cd7a2c19 --- /dev/null +++ b/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c @@ -0,0 +1,378 @@ +/* + * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2013, Grasshopper + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is Grasshopper + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Rienzo + * + * rayo_receivefax_component.c -- Rayo receivefax component implementation + * + */ +#include "rayo_components.h" +#include "rayo_elements.h" + +/** + * settings + */ +static struct { + const char *file_prefix; +} globals; + +struct receivefax_component { + /** component base class */ + struct rayo_component base; + /** true if HTTP PUT needs to be done after fax is received */ + int http_put_after_receive; + /** fax stored on local filesystem */ + const char *local_filename; + /** fax final target (may be same as local filename) */ + const char *filename; + /** Flag to stop fax */ + int stop; +}; + +#define RECEIVEFAX_FINISH "finish", RAYO_FAX_COMPLETE_NS + +#define RECEIVEFAX_COMPONENT(x) ((struct receivefax_component *)x) + +/** + * Start execution of call receivefax component + * @param call the call to receive fax from + * @param msg the original request + * @param session_data the call's session + */ +static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) +{ + iks *iq = msg->payload; + switch_core_session_t *session = (switch_core_session_t *)session_data; + struct receivefax_component *receivefax_component = NULL; + iks *receivefax = iks_find(iq, "receivefax"); + iks *response = NULL; + switch_event_t *execute_event = NULL; + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_memory_pool_t *pool; + int file_no; + + /* validate attributes */ + if (!VALIDATE_RAYO_RECEIVEFAX(receivefax)) { + return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); + } + + /* fax is only allowed if the call is not currently joined */ + if (rayo_call_is_joined(RAYO_CALL(call))) { + return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't receive fax on a joined call"); + } + + if (!rayo_call_set_faxing(RAYO_CALL(call), 1)) { + return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress"); + } + + /* create receivefax component */ + switch_core_new_memory_pool(&pool); + receivefax_component = switch_core_alloc(pool, sizeof(*receivefax_component)); + rayo_component_init((struct rayo_component *)receivefax_component, pool, RAT_CALL_COMPONENT, "receivefax", NULL, call, iks_find_attrib(iq, "from")); + file_no = rayo_actor_seq_next(call); + receivefax_component->filename = switch_core_sprintf(pool, "%s%s%s-%d", + globals.file_prefix, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no); + if (!strncmp(receivefax_component->filename, "http://", 7) || strncmp(receivefax_component->filename, "https://", 8)) { + /* This is an HTTP URL, need to PUT after fax is received */ + receivefax_component->local_filename = switch_core_sprintf(pool, "%s%s%s-%d", + SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no); + receivefax_component->http_put_after_receive = 1; + } else { + /* assume file.. */ + receivefax_component->local_filename = receivefax_component->filename; + } + + /* add channel variable so that fax component can be located from fax events */ + switch_channel_set_variable(channel, "rayo_fax_jid", RAYO_JID(receivefax_component)); + + /* clear fax result variables */ + switch_channel_set_variable(channel, "fax_success", NULL); + switch_channel_set_variable(channel, "fax_result_code", NULL); + switch_channel_set_variable(channel, "fax_result_text", NULL); + switch_channel_set_variable(channel, "fax_document_transferred_pages", NULL); + switch_channel_set_variable(channel, "fax_document_total_pages", NULL); + switch_channel_set_variable(channel, "fax_image_resolution", NULL); + switch_channel_set_variable(channel, "fax_image_size", NULL); + switch_channel_set_variable(channel, "fax_bad_rows", NULL); + switch_channel_set_variable(channel, "fax_transfer_rate", NULL); + switch_channel_set_variable(channel, "fax_ecm_used", NULL); + switch_channel_set_variable(channel, "fax_local_station_id", NULL); + switch_channel_set_variable(channel, "fax_remote_station_id", NULL); + + /* clear fax interrupt variable */ + switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); + + /* execute rxfax APP */ + if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "rxfax"); + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", receivefax_component->local_filename); + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); + if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { + switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); + } + + if (switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { + response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to rxfax (queue event failed)"); + if (execute_event) { + switch_event_destroy(&execute_event); + } + RAYO_UNLOCK(receivefax_component); + } else { + /* component starting... */ + rayo_component_send_start(RAYO_COMPONENT(receivefax_component), iq); + } + } else { + response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create rxfax event"); + RAYO_UNLOCK(receivefax_component); + } + + return response; +} + +/** + * Stop execution of receivefax component + */ +static iks *stop_receivefax_component(struct rayo_actor *component, struct rayo_message *msg, void *data) +{ + iks *iq = msg->payload; + switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id); + if (session) { + /* fail on read frame until component is destroyed */ + switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", RAYO_JID(component)); + switch_core_session_rwunlock(session); + } + RECEIVEFAX_COMPONENT(component)->stop = 1; + return iks_new_iq_result(iq); +} + +/** + * Add fax metadata to result + * @param event source of metadata + * @param name of metadata + * @param result to add metadata to + */ +static void insert_fax_metadata(switch_event_t *event, const char *name, iks *result) +{ + char actual_name[256]; + const char *value; + snprintf(actual_name, sizeof(actual_name), "variable_%s", name); + actual_name[sizeof(actual_name) - 1] = '\0'; + value = switch_event_get_header(event, actual_name); + if (!zstr(value)) { + iks *metadata = iks_insert(result, "metadata"); + iks_insert_attrib(metadata, "xmlns", RAYO_FAX_COMPLETE_NS); + iks_insert_attrib(metadata, "name", name); + iks_insert_attrib(metadata, "value", value); + } +} + +/** + * Handle rxfax execute event + * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. + */ +static void on_execute_event(switch_event_t *event) +{ + const char *application = switch_event_get_header(event, "Application"); + if (!zstr(application) && !strcmp(application, "rxfax")) { + /* TODO */ + } +} + +/** + * Handle rxfax completion event from FreeSWITCH core + * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. + */ +static void on_execute_complete_event(switch_event_t *event) +{ + const char *application = switch_event_get_header(event, "Application"); + if (!zstr(application) && !strcmp(application, "rxfax")) { + const char *uuid = switch_event_get_header(event, "Unique-ID"); + const char *fax_jid = switch_event_get_header(event, "variable_rayo_fax_jid"); + struct rayo_actor *component; + if (!zstr(fax_jid) && (component = RAYO_LOCATE(fax_jid))) { + const char *url = RECEIVEFAX_COMPONENT(component)->filename; + iks *result; + iks *complete; + iks *fax; + switch_core_session_t *session; + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid); + + /* clean up channel */ + session = switch_core_session_locate(uuid); + if (session) { + switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); + switch_core_session_rwunlock(session); + } + + /* flag faxing as done */ + rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0); + + /* successful fax? */ + if (switch_true(switch_event_get_header(event, "variable_fax_success"))) { + result = rayo_component_create_complete_event(RAYO_COMPONENT(component), RECEIVEFAX_FINISH); + } else if (RECEIVEFAX_COMPONENT(component)->stop) { + result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); + } else { + result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); + } + complete = iks_find(result, "complete"); + + /* add fax document information */ + { + const char *pages = switch_event_get_header(event, "variable_fax_document_transferred_pages"); + if (!zstr(pages) && switch_is_number(pages) && atoi(pages) > 0) { + const char *resolution = switch_event_get_header(event, "variable_fax_file_image_resolution"); + const char *size = switch_event_get_header(event, "variable_fax_image_size"); + + fax = iks_insert(complete, "fax"); + iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS); + + if (strlen(url) > strlen(SWITCH_PATH_SEPARATOR) && !strncmp(url, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) { + /* convert absolute path to file:// URI */ + iks_insert_attrib_printf(fax, "url", "file://%s", url); + } else { + /* is already a URI (hopefully) */ + iks_insert_attrib(fax, "url", url); + } + + if (!zstr(resolution)) { + iks_insert_attrib(fax, "resolution", resolution); + } + if (!zstr(size)) { + iks_insert_attrib(fax, "size", size); + } + iks_insert_attrib(fax, "pages", pages); + } + + /* TODO transfer HTTP document and delete local copy */ + } + + /* add metadata from event */ + insert_fax_metadata(event, "fax_success", complete); + insert_fax_metadata(event, "fax_result_code", complete); + insert_fax_metadata(event, "fax_result_text", complete); + insert_fax_metadata(event, "fax_document_transferred_pages", complete); + insert_fax_metadata(event, "fax_document_total_pages", complete); + insert_fax_metadata(event, "fax_image_resolution", complete); + insert_fax_metadata(event, "fax_image_size", complete); + insert_fax_metadata(event, "fax_bad_rows", complete); + insert_fax_metadata(event, "fax_transfer_rate", complete); + insert_fax_metadata(event, "fax_ecm_used", complete); + insert_fax_metadata(event, "fax_local_station_id", complete); + insert_fax_metadata(event, "fax_remote_station_id", complete); + + rayo_component_send_complete_event(RAYO_COMPONENT(component), result); + + RAYO_UNLOCK(component); + } + } +} + +/** + * Process module XML configuration + * @param pool memory pool to allocate from + * @param config_file to use + * @return SWITCH_STATUS_SUCCESS on successful configuration + */ +static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) +{ + switch_xml_t cfg, xml; + + /* set defaults */ + globals.file_prefix = switch_core_sprintf(pool, "%s%s", SWITCH_GLOBAL_dirs.recordings_dir, SWITCH_PATH_SEPARATOR); + + if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); + return SWITCH_STATUS_TERM; + } + + /* get params */ + { + switch_xml_t settings = switch_xml_child(cfg, "receivefax"); + if (settings) { + switch_xml_t param; + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + const char *var = switch_xml_attr_soft(param, "name"); + const char *val = switch_xml_attr_soft(param, "value"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); + if (!strcasecmp(var, "file-prefix")) { + if (!zstr(val)) { + globals.file_prefix = switch_core_strdup(pool, val); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); + } + } + } + } + + switch_xml_free(xml); + + return SWITCH_STATUS_SUCCESS; +} + +/** + * Initialize receivefax component + * @param module_interface + * @param pool memory pool to allocate from + * @param config_file to use + * @return SWITCH_STATUS_SUCCESS if successful + */ +switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) +{ + if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_TERM; + } + + switch_event_bind("rayo_receivefax_component", SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, on_execute_complete_event, NULL); + switch_event_bind("rayo_receivefax_component", SWITCH_EVENT_CHANNEL_EXECUTE, NULL, on_execute_event, NULL); + + rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":receivefax", start_receivefax_component); + rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "receivefax", "set:"RAYO_EXT_NS":stop", stop_receivefax_component); + + return SWITCH_STATUS_SUCCESS; +} + +/** + * Shutdown receivefax component + * @return SWITCH_STATUS_SUCCESS if successful + */ +switch_status_t rayo_receivefax_component_shutdown(void) +{ + switch_event_unbind_callback(on_execute_event); + switch_event_unbind_callback(on_execute_complete_event); + + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet + */ From 8bc0f99e70d2bdcf9b42ce4ce5ea8f07b51c2334 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 6 Nov 2013 17:57:31 -0500 Subject: [PATCH 033/656] mod_rayo: now supports HTTP(S) --- .../mod_rayo/rayo_receivefax_component.c | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c b/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c index 09cd7a2c19..75528f8b52 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c @@ -92,14 +92,16 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess file_no = rayo_actor_seq_next(call); receivefax_component->filename = switch_core_sprintf(pool, "%s%s%s-%d", globals.file_prefix, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no); - if (!strncmp(receivefax_component->filename, "http://", 7) || strncmp(receivefax_component->filename, "https://", 8)) { + if (!strncmp(receivefax_component->filename, "http://", 7) || !strncmp(receivefax_component->filename, "https://", 8)) { /* This is an HTTP URL, need to PUT after fax is received */ receivefax_component->local_filename = switch_core_sprintf(pool, "%s%s%s-%d", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no); receivefax_component->http_put_after_receive = 1; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to HTTP URL\n", RAYO_JID(receivefax_component)); } else { /* assume file.. */ receivefax_component->local_filename = receivefax_component->filename; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s save fax to local file\n", RAYO_JID(receivefax_component)); } /* add channel variable so that fax component can be located from fax events */ @@ -187,18 +189,6 @@ static void insert_fax_metadata(switch_event_t *event, const char *name, iks *re } } -/** - * Handle rxfax execute event - * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. - */ -static void on_execute_event(switch_event_t *event) -{ - const char *application = switch_event_get_header(event, "Application"); - if (!zstr(application) && !strcmp(application, "rxfax")) { - /* TODO */ - } -} - /** * Handle rxfax completion event from FreeSWITCH core * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. @@ -215,6 +205,7 @@ static void on_execute_complete_event(switch_event_t *event) iks *result; iks *complete; iks *fax; + int have_fax_document = 1; switch_core_session_t *session; switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid); @@ -228,10 +219,26 @@ static void on_execute_complete_event(switch_event_t *event) /* flag faxing as done */ rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0); + /* transfer HTTP document and delete local copy */ + if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component))) { + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename); + switch_api_execute("http_put", RECEIVEFAX_COMPONENT(component)->filename, NULL, &stream); + /* check if successful */ + if (!zstr(stream.data) && strncmp(stream.data, "+OK", 3)) { + /* PUT failed */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename, (char *)stream.data); + have_fax_document = 0; + } + switch_safe_free(stream.data) + switch_file_remove(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)); + } + /* successful fax? */ - if (switch_true(switch_event_get_header(event, "variable_fax_success"))) { + if (have_fax_document && switch_true(switch_event_get_header(event, "variable_fax_success"))) { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), RECEIVEFAX_FINISH); - } else if (RECEIVEFAX_COMPONENT(component)->stop) { + } else if (have_fax_document && RECEIVEFAX_COMPONENT(component)->stop) { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); } else { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); @@ -239,7 +246,7 @@ static void on_execute_complete_event(switch_event_t *event) complete = iks_find(result, "complete"); /* add fax document information */ - { + if (have_fax_document) { const char *pages = switch_event_get_header(event, "variable_fax_document_transferred_pages"); if (!zstr(pages) && switch_is_number(pages) && atoi(pages) > 0) { const char *resolution = switch_event_get_header(event, "variable_fax_file_image_resolution"); @@ -248,12 +255,11 @@ static void on_execute_complete_event(switch_event_t *event) fax = iks_insert(complete, "fax"); iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS); - if (strlen(url) > strlen(SWITCH_PATH_SEPARATOR) && !strncmp(url, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) { + if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive) { + iks_insert_attrib(fax, "url", url); + } else { /* convert absolute path to file:// URI */ iks_insert_attrib_printf(fax, "url", "file://%s", url); - } else { - /* is already a URI (hopefully) */ - iks_insert_attrib(fax, "url", url); } if (!zstr(resolution)) { @@ -264,8 +270,6 @@ static void on_execute_complete_event(switch_event_t *event) } iks_insert_attrib(fax, "pages", pages); } - - /* TODO transfer HTTP document and delete local copy */ } /* add metadata from event */ @@ -327,6 +331,8 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ } } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax file-prefix = %s\n", globals.file_prefix); + switch_xml_free(xml); return SWITCH_STATUS_SUCCESS; @@ -346,7 +352,6 @@ switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_ } switch_event_bind("rayo_receivefax_component", SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, on_execute_complete_event, NULL); - switch_event_bind("rayo_receivefax_component", SWITCH_EVENT_CHANNEL_EXECUTE, NULL, on_execute_event, NULL); rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":receivefax", start_receivefax_component); rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "receivefax", "set:"RAYO_EXT_NS":stop", stop_receivefax_component); @@ -360,7 +365,6 @@ switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_ */ switch_status_t rayo_receivefax_component_shutdown(void) { - switch_event_unbind_callback(on_execute_event); switch_event_unbind_callback(on_execute_complete_event); return SWITCH_STATUS_SUCCESS; From 69035ff412c80551566b1fc73d34fa8f91e79378 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 7 Nov 2013 16:14:03 -0500 Subject: [PATCH 034/656] mod_rayo: add fax to service discovery query --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index c5a57eeda5..51d1614751 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -2371,11 +2371,14 @@ static iks *on_iq_get_xmpp_disco(struct rayo_actor *server, struct rayo_message iks *node = msg->payload; iks *response = NULL; iks *x; + iks *feature; response = iks_new_iq_result(node); x = iks_insert(response, "query"); iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_DISCO); - x = iks_insert(x, "feature"); - iks_insert_attrib(x, "var", RAYO_NS); + feature = iks_insert(x, "feature"); + iks_insert_attrib(feature, "var", RAYO_NS); + feature = iks_insert(x, "feature"); + iks_insert_attrib(feature, "var", RAYO_FAX_NS); /* TODO The response MUST also include features for the application formats and transport methods supported by * the responding entity, as described in the relevant specifications. From 73c4eb5f106f30ec194ee7b740e4733aeaa55533 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Nov 2013 03:44:21 +0500 Subject: [PATCH 035/656] add 8k support for opus --- src/mod/codecs/mod_opus/mod_opus.c | 282 +++++++++++++++++++++++++++-- 1 file changed, 270 insertions(+), 12 deletions(-) diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index b1681ea5fa..f3d5585fdf 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -36,35 +36,229 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load); SWITCH_MODULE_DEFINITION(mod_opus, mod_opus_load, NULL, NULL); +/*! \brief Various codec settings */ +struct opus_codec_settings { + int useinbandfec; + int usedtx; + int maxaveragebitrate; + int stereo; + int cbr; + int sprop_maxcapturerate; + int sprop_stereo; + int maxptime; + int minptime; + int ptime; + int samplerate; +}; +typedef struct opus_codec_settings opus_codec_settings_t; + +static opus_codec_settings_t default_codec_settings = { + /*.useinbandfec */ 1, + /*.usedtx */ 1, + /*.maxaveragebitrate */ 30000, + /*.stereo*/ 0, + /*.cbr*/ 0, + /*.sprop_maxcapturerate*/ 0, + /*.sprop_stereo*/ 0, + /*.maxptime*/ 0, + /*.minptime*/ 0, + /*.ptime*/ 0, + /*.samplerate*/ 0 +}; + struct opus_context { OpusEncoder *encoder_object; OpusDecoder *decoder_object; int frame_size; }; +static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmtp_t *codec_fmtp) +{ + if (codec_fmtp) { + opus_codec_settings_t local_settings = { 0 }; + opus_codec_settings_t *codec_settings = &local_settings; + + if (codec_fmtp->private_info) { + codec_settings = codec_fmtp->private_info; + if (zstr(fmtp)) { + memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); + } + } + + if (fmtp) { + int x, argc; + char *argv[10]; + char *fmtp_dup = strdup(fmtp); + + switch_assert(fmtp_dup); + + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + for (x = 0; x < argc; x++) { + char *data = argv[x]; + char *arg; + switch_assert(data); + while (*data == ' ') { + data++; + } + + + if ((arg = strchr(data, '='))) { + *arg++ = '\0'; + + if (codec_settings) { + if (!strcasecmp(data, "useinbandfec")) { + codec_settings->useinbandfec = switch_true(arg); + } + + if (!strcasecmp(data, "usedtx")) { + codec_settings->usedtx = switch_true(arg); + } + + if (!strcasecmp(data, "sprop-maxcapturerate")) { + codec_settings->sprop_maxcapturerate = atoi(arg); + } + + if (!strcasecmp(data, "maxptime")) { + codec_settings->maxptime = atoi(arg); + } + + if (!strcasecmp(data, "minptime")) { + codec_settings->minptime = atoi(arg); + } + + if (!strcasecmp(data, "ptime")) { + codec_settings->ptime = atoi(arg); + codec_fmtp->microseconds_per_packet = codec_settings->ptime * 1000; + } + + if (!strcasecmp(data, "samplerate")) { + codec_settings->samplerate = atoi(arg); + codec_fmtp->actual_samples_per_second = codec_settings->samplerate; + } + + if (!strcasecmp(data, "maxaveragebitrate")) { + codec_settings->maxaveragebitrate = atoi(arg); + switch(codec_fmtp->actual_samples_per_second) { + case 8000: + { + if(codec_settings->maxaveragebitrate < 6000 || codec_settings->maxaveragebitrate > 20000) { + codec_settings->maxaveragebitrate = 20000; + } + break; + } + case 12000: + { + if(codec_settings->maxaveragebitrate < 7000 || codec_settings->maxaveragebitrate > 25000) { + codec_settings->maxaveragebitrate = 25000; + } + break; + } + case 16000: + { + if(codec_settings->maxaveragebitrate < 8000 || codec_settings->maxaveragebitrate > 30000) { + codec_settings->maxaveragebitrate = 30000; + } + break; + } + case 24000: + { + if(codec_settings->maxaveragebitrate < 12000 || codec_settings->maxaveragebitrate > 40000) { + codec_settings->maxaveragebitrate = 40000; + } + break; + } + + default: + /* this should never happen but 20000 is common among all rates */ + codec_settings->maxaveragebitrate = 20000; + break; + } + + + codec_fmtp->bits_per_second = codec_settings->maxaveragebitrate; + } + + } + } + } + free(fmtp_dup); + } + //codec_fmtp->bits_per_second = bit_rate; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + +static char *gen_fmtp(opus_codec_settings_t *settings, switch_memory_pool_t *pool) +{ + char buf[256] = ""; + + if (settings->useinbandfec) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "useinbandfec=1;"); + } + + if (settings->usedtx) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "usedtx=1;"); + } + + if (settings->maxaveragebitrate) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "maxaveragebitrate=%d;", settings->maxaveragebitrate); + + } + + if (settings->ptime) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "ptime=%d;", settings->ptime); + } + + if (settings->minptime) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "minptime=%d;", settings->minptime); + } + + if (settings->maxptime) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "maxptime=%d;", settings->maxptime); + } + + if (settings->samplerate) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "samplerate=%d;", settings->samplerate); + } + + if (end_of(buf) == ';') { + end_of(buf) = '\0'; + } + + return switch_core_strdup(pool, buf); + +} + static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) { struct opus_context *context = NULL; int encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); int decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + switch_codec_fmtp_t codec_fmtp; + opus_codec_settings_t opus_codec_settings = { 0 }; if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } context->frame_size = codec->implementation->samples_per_packet; - + + memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); + codec_fmtp.private_info = &opus_codec_settings; + switch_opus_fmtp_parse(codec->fmtp_in, &codec_fmtp); + + codec->fmtp_out = gen_fmtp(&opus_codec_settings, codec->memory_pool); + if (encoding) { /* come up with a way to specify these */ - int bitrate_bps = codec->implementation->bits_per_second; + int bitrate_bps = OPUS_AUTO; int use_vbr = 1; int complexity = 10; - int use_inbandfec = 1; - int use_dtx = 1; - int bandwidth = OPUS_BANDWIDTH_FULLBAND; int err; + int samplerate = opus_codec_settings.samplerate ? opus_codec_settings.samplerate : codec->implementation->actual_samples_per_second; - context->encoder_object = opus_encoder_create(codec->implementation->actual_samples_per_second, + context->encoder_object = opus_encoder_create(samplerate, codec->implementation->number_of_channels, OPUS_APPLICATION_VOIP, &err); @@ -74,12 +268,24 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag } opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); - opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(bandwidth)); + + if (codec->implementation->actual_samples_per_second == 8000) { + opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + } else { + opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + } + opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr)); opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity)); - opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(use_inbandfec)); - opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX(use_dtx)); + if (opus_codec_settings.useinbandfec) { + opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(opus_codec_settings.useinbandfec)); + } + + if (opus_codec_settings.usedtx) { + opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX(opus_codec_settings.usedtx)); + } } if (decoding) { @@ -187,19 +393,33 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) int mss = 10000; int x = 0; int rate = 48000; - int bits = 32000; + int bits = 0; + char *dft_fmtp = NULL; + opus_codec_settings_t settings = { 0 }; /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "OPUS (STANDARD)"); + codec_interface->parse_fmtp = switch_opus_fmtp_parse; + + settings = default_codec_settings; + + for (x = 0; x < 3; x++) { + + settings.ptime = mss / 1000; + settings.maxptime = settings.ptime; + settings.minptime = settings.ptime; + settings.samplerate = rate; + dft_fmtp = gen_fmtp(&settings, pool); + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ 116, /* the IANA code number */ "opus",/* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - rate, /* samples transferred per second */ + dft_fmtp, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ rate, /* actual samples transferred per second */ bits, /* bits transferred per second */ mss, /* number of microseconds per frame */ @@ -219,6 +439,44 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) } + + samples = 80; + bytes = 160; + mss = 10000; + rate = 8000; + + for (x = 0; x < 3; x++) { + + settings.ptime = mss / 1000; + settings.maxptime = settings.ptime; + settings.minptime = settings.ptime; + settings.samplerate = rate; + dft_fmtp = gen_fmtp(&settings, pool); + + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 116, /* the IANA code number */ + "opus",/* the IANA code name */ + dft_fmtp, /* default fmtp to send (can be overridden by the init function) */ + 48000, /* samples transferred per second */ + rate, /* actual samples transferred per second */ + bits, /* bits transferred per second */ + mss, /* number of microseconds per frame */ + samples, /* number of samples per frame */ + bytes, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 1,/* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + + bytes += 160; + samples += 80; + mss += 10000; + + } + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } From bb9adff511b8712681bc18b0b1715f1ebd28eeb7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Nov 2013 03:48:00 +0500 Subject: [PATCH 036/656] rework media code --- src/include/private/switch_core_pvt.h | 1 + src/include/switch_core_media.h | 62 +- src/include/switch_frame.h | 2 + src/include/switch_rtp.h | 3 +- .../mod_conference/mod_conference.c | 18 +- src/mod/codecs/mod_vp8/mod_vp8.c | 12 + src/mod/endpoints/mod_sofia/mod_sofia.c | 33 +- src/mod/endpoints/mod_sofia/rtp.c | 2 +- src/mod/endpoints/mod_sofia/sofia.c | 20 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- src/switch_core_io.c | 9 +- src/switch_core_media.c | 1696 +++++++++-------- src/switch_rtp.c | 108 +- src/switch_utils.c | 2 +- 14 files changed, 1166 insertions(+), 804 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index bff9b72a78..aa6adb67e9 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -178,6 +178,7 @@ struct switch_core_session { switch_size_t recur_buffer_len; switch_media_handle_t *media_handle; + uint32_t decoder_errors; }; struct switch_media_bug { diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 9641718f07..5c083101a9 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -68,7 +68,6 @@ typedef enum { SCMF_RUNNING, SCMF_DISABLE_TRANSCODING, SCMF_AUTOFIX_TIMING, - SCMF_AUTOFIX_PT, SCMF_CODEC_GREEDY, SCMF_CODEC_SCROOGE, SCMF_DISABLE_HOLD, @@ -81,6 +80,8 @@ typedef enum { SCMF_AUTOFLUSH, SCMF_REWRITE_TIMESTAMPS, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE, + SCMF_MULTI_ANSWER_AUDIO, + SCMF_MULTI_ANSWER_VIDEO, SCMF_MAX } switch_core_media_flag_t; @@ -156,6 +157,53 @@ typedef struct switch_core_media_params_s { } switch_core_media_params_t; +typedef struct xpayload_map_s { + uint32_t pt; + uint32_t send_pt; + uint32_t rate; + uint32_t ptime; + switch_media_type_t type; + uint8_t negotiated; + char *name; + switch_sdp_type_t sdp_type; + unsigned long hash; + struct xpayload_map_s *next; +} xpayload_map_t; + +typedef struct payload_map_s { + switch_media_type_t type; + switch_sdp_type_t sdp_type; + uint32_t ptime; + uint32_t rate; + uint8_t allocated; + uint8_t negotiated; + unsigned long hash; + + char *rm_encoding; + char *iananame; + switch_payload_t pt; + unsigned long rm_rate; + unsigned long adv_rm_rate; + uint32_t codec_ms; + uint32_t bitrate; + + char *rm_fmtp; + + switch_payload_t agreed_pt; + switch_payload_t recv_pt; + + char *fmtp_out; + + char *remote_sdp_ip; + switch_port_t remote_sdp_port; + + int channels; + int adv_channels; + + struct payload_map_s *next; + +} payload_map_t; + static inline const char *switch_media_type2str(switch_media_type_t type) { switch(type) { @@ -216,7 +264,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip); SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_core_session_t *session, switch_core_session_t *other_session, switch_t38_options_t *t38_options); -SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *session, const char *ip, switch_port_t port, const char *sr, int force); +SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *session, switch_sdp_type_t sdp_type, + const char *ip, switch_port_t port, const char *sr, int force); SWITCH_DECLARE(void)switch_core_media_set_local_sdp(switch_core_session_t *session, const char *sdp_str, switch_bool_t dup); SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t *session, switch_t38_options_t *t38_options, int insist); @@ -232,7 +281,6 @@ SWITCH_DECLARE(void) switch_core_media_kill_socket(switch_core_session_t *sessio SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf); SWITCH_DECLARE(switch_status_t) switch_core_media_queue_rfc2833_in(switch_core_session_t *session, switch_media_type_t type, const switch_dtmf_t *dtmf); SWITCH_DECLARE(uint8_t) switch_core_media_ready(switch_core_session_t *session, switch_media_type_t type); -SWITCH_DECLARE(void) switch_core_media_set_recv_pt(switch_core_session_t *session, switch_media_type_t type, switch_payload_t pt); SWITCH_DECLARE(void) switch_core_media_set_telephony_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te); SWITCH_DECLARE(void) switch_core_media_set_telephony_recv_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te); SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool); @@ -257,6 +305,14 @@ SWITCH_DECLARE(void) switch_core_media_deinit(void); SWITCH_DECLARE(void) switch_core_media_set_stats(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_wake_video_thread(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_clear_crypto(switch_core_session_t *session); +SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session, + switch_media_type_t type, + const char *name, + switch_sdp_type_t sdp_type, + uint32_t pt, + uint32_t rate, + uint32_t ptime, + uint8_t negotiated); SWITCH_END_EXTERN_C #endif diff --git a/src/include/switch_frame.h b/src/include/switch_frame.h index 39ffb9ca6b..4e46b61d2f 100644 --- a/src/include/switch_frame.h +++ b/src/include/switch_frame.h @@ -37,6 +37,7 @@ #define SWITCH_FRAME_H #include +#include SWITCH_BEGIN_EXTERN_C /*! \brief An abstraction of a data frame */ @@ -71,6 +72,7 @@ SWITCH_BEGIN_EXTERN_C /*! frame flags */ switch_frame_flag_t flags; void *user_data; + payload_map_t *pmap; }; SWITCH_END_EXTERN_C diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index bd509cc29a..ca0b3f3b8d 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -485,7 +485,6 @@ SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *pri */ SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te); SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_session, switch_payload_t te); -SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt); /*! \brief Set the payload type for comfort noise @@ -500,7 +499,7 @@ SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_pay \return the pointer to the private data */ SWITCH_DECLARE(void *) switch_rtp_get_private(switch_rtp_t *rtp_session); - +SWITCH_DECLARE(switch_status_t) switch_rtp_set_payload_map(switch_rtp_t *rtp_session, payload_map_t **pmap); SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs); SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 8f3f1a81b8..2d7a9df244 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -184,7 +184,8 @@ typedef enum { MFLAG_NOMOH = (1 << 19), MFLAG_VIDEO_BRIDGE = (1 << 20), MFLAG_INDICATE_MUTE_DETECT = (1 << 21), - MFLAG_PAUSE_RECORDING = (1 << 22) + MFLAG_PAUSE_RECORDING = (1 << 22), + MFLAG_ACK_VIDEO = (1 << 23) } member_flag_t; typedef enum { @@ -1796,6 +1797,10 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe channel = switch_core_session_get_channel(member->session); + if (switch_channel_test_flag(channel, CF_VIDEO)) { + switch_set_flag_locked(member, MFLAG_ACK_VIDEO); + } + switch_channel_set_variable_printf(channel, "conference_member_id", "%d", member->id); switch_channel_set_variable_printf(channel, "conference_moderator", "%s", switch_test_flag(member, MFLAG_MOD) ? "true" : "false"); switch_channel_set_variable(channel, "conference_recording", conference->record_filename); @@ -2595,6 +2600,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v char *rfile = switch_channel_expand_variables(channel, conference->auto_record); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Auto recording file: %s\n", rfile); launch_conference_record_thread(conference, rfile, SWITCH_TRUE); + if (rfile != conference->auto_record) { conference->record_filename = switch_core_strdup(conference->pool, rfile); switch_safe_free(rfile); @@ -3639,6 +3645,12 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v break; } + if (switch_channel_test_flag(channel, CF_VIDEO) && !switch_test_flag(member, MFLAG_ACK_VIDEO)) { + switch_set_flag_locked(member, MFLAG_ACK_VIDEO); + switch_channel_clear_flag(channel, CF_VIDEO_ECHO); + switch_core_session_refresh_video(member->session); + } + /* if we have caller digits, feed them to the parser to find an action */ if (switch_channel_has_dtmf(channel)) { char dtmf[128] = ""; @@ -8410,8 +8422,8 @@ SWITCH_STANDARD_APP(conference_function) msg.from = __FILE__; /* Tell the channel we are going to be in a bridge */ - msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; - switch_core_session_receive_message(session, &msg); + //msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; + //switch_core_session_receive_message(session, &msg); /* Run the conference loop */ conference_loop_output(&member); diff --git a/src/mod/codecs/mod_vp8/mod_vp8.c b/src/mod/codecs/mod_vp8/mod_vp8.c index 121b9ab0c9..0fe64c72b8 100644 --- a/src/mod/codecs/mod_vp8/mod_vp8.c +++ b/src/mod/codecs/mod_vp8/mod_vp8.c @@ -83,9 +83,21 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vp8_load) /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_CODEC(codec_interface, "VP8 Video (passthru)"); + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_VIDEO, 99, "VP8", NULL, 90000, 90000, 0, 0, 0, 0, 0, 1, 1, switch_vp8_init, switch_vp8_encode, switch_vp8_decode, switch_vp8_destroy); + + SWITCH_ADD_CODEC(codec_interface, "red Video (passthru)"); + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_VIDEO, 103, "red", NULL, 90000, 90000, 0, + 0, 0, 0, 0, 1, 1, switch_vp8_init, switch_vp8_encode, switch_vp8_decode, switch_vp8_destroy); + + SWITCH_ADD_CODEC(codec_interface, "ulpfec Video (passthru)"); + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_VIDEO, 103, "ulpfec", NULL, 90000, 90000, 0, + 0, 0, 0, 0, 1, 1, switch_vp8_init, switch_vp8_encode, switch_vp8_decode, switch_vp8_destroy); + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 7286c5de16..dc6351799d 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -626,13 +626,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY nomedia - sending ack\n"); nua_ack(tech_pvt->nh, - TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), - SIPTAG_CONTACT_STR(tech_pvt->reply_contact), - SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), - SOATAG_REUSE_REJECTED(1), - SOATAG_RTP_SELECT(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), - TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), - TAG_END()); + TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + SIPTAG_CONTACT_STR(tech_pvt->reply_contact), + SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), + SOATAG_REUSE_REJECTED(1), + SOATAG_RTP_SELECT(1), + SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), + TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), + TAG_END()); sofia_clear_flag(tech_pvt, TFLAG_3PCC_INVITE); // all done sofia_set_flag_locked(tech_pvt, TFLAG_ANS); sofia_set_flag_locked(tech_pvt, TFLAG_SDP); @@ -667,7 +668,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) tech_pvt->mparams.local_sdp_str = NULL; switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); } else { switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); @@ -683,12 +684,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX); if (sofia_use_soa(tech_pvt)) { + nua_respond(tech_pvt->nh, SIP_200_OK, TAG_IF(is_proxy, NUTAG_AUTOANSWER(0)), SIPTAG_CONTACT_STR(tech_pvt->profile->url), SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), - SOATAG_REUSE_REJECTED(1), TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)), + SOATAG_REUSE_REJECTED(1), + SOATAG_RTP_SELECT(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote), @@ -762,7 +765,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) return status; } - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } @@ -834,7 +837,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), - TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)), + SOATAG_RTP_SELECT(1), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote), SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END()); @@ -1221,7 +1224,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_set_flag(tech_pvt->channel, CF_SECURE); } - if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING) || sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_PT)) { + if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) { switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO); } } @@ -1264,7 +1267,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi ip = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE); port = switch_channel_get_variable(channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE); if (ip && port) { - switch_core_media_gen_local_sdp(session, ip, (switch_port_t)atoi(port), msg->string_arg, 1); + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), msg->string_arg, 1); } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { @@ -1397,7 +1400,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi goto end_lock; } } - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); if (send_invite) { if (!switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { @@ -2081,7 +2084,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); goto end_lock; } - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } diff --git a/src/mod/endpoints/mod_sofia/rtp.c b/src/mod/endpoints/mod_sofia/rtp.c index a34b8cfd74..a1467f9647 100644 --- a/src/mod/endpoints/mod_sofia/rtp.c +++ b/src/mod/endpoints/mod_sofia/rtp.c @@ -513,7 +513,7 @@ static switch_status_t channel_receive_event(switch_core_session_t *session, swi } switch_rtp_set_default_payload(tech_pvt->rtp_session, pt); - switch_rtp_set_recv_pt(tech_pvt->rtp_session, pt); + //switch_rtp_set_recv_pt(tech_pvt->rtp_session, pt); } if (compare_var(event, channel, kRFC2833PT)) { diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f2194487d4..0a98cbf983 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3743,7 +3743,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) sofia_set_pflag(profile, PFLAG_DISABLE_100REL); profile->auto_restart = 1; sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING); - sofia_set_media_flag(profile, SCMF_AUTOFIX_PT); + sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE); sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE); profile->contact_user = SOFIA_DEFAULT_CONTACT_USER; sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID); @@ -4381,12 +4381,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_media_flag(profile, SCMF_AUTOFIX_TIMING); } - } else if (!strcasecmp(var, "rtp-autofix-pt")) { - if (switch_true(val)) { - sofia_set_media_flag(profile, SCMF_AUTOFIX_PT); - } else { - sofia_clear_media_flag(profile, SCMF_AUTOFIX_PT); - } } else if (!strcasecmp(var, "contact-user")) { profile->contact_user = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "nat-options-ping")) { @@ -5250,7 +5244,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status sofia_update_callee_id(session, profile, sip, SWITCH_FALSE); - if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING) || sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_PT)) { + if (sofia_test_media_flag(tech_pvt->profile, SCMF_AUTOFIX_TIMING)) { switch_core_media_reset_autofix(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO); } @@ -6204,7 +6198,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } else { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP"); switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); sofia_set_flag_locked(tech_pvt, TFLAG_3PCC); switch_channel_set_state(channel, CS_HIBERNATE); if (sofia_use_soa(tech_pvt)) { @@ -6321,7 +6315,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } } - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 1); if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -6427,7 +6421,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, goto done; } - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite RTP Error!\n"); @@ -6446,7 +6440,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (is_ok) { if (switch_core_session_local_crypto_key(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) { - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); } if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -6486,7 +6480,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) { goto done; } - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n"); switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 833a725d44..d5bbe14c55 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -752,7 +752,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) } if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)) { - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); } sofia_set_flag_locked(tech_pvt, TFLAG_READY); diff --git a/src/switch_core_io.c b/src/switch_core_io.c index b1b42c7f1f..1a5a0469fe 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -644,8 +644,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi default: switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec %s decoder error! [%d]\n", session->read_codec->codec_interface->interface_name, status); - goto done; + + if (++session->decoder_errors < 10) { + status = SWITCH_STATUS_SUCCESS; + } else { + goto done; + } } + + session->decoder_errors = 0; } if (session->bugs) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d18b648546..59eacde94c 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -68,36 +68,7 @@ typedef struct secure_settings_s { char *remote_crypto_key; } switch_secure_settings_t; -typedef struct codec_params_s { - char *rm_encoding; - char *iananame; - switch_payload_t pt; - unsigned long rm_rate; - unsigned long adv_rm_rate; - uint32_t codec_ms; - uint32_t bitrate; - char *rm_fmtp; - - switch_payload_t agreed_pt; - switch_payload_t recv_pt; - char *fmtp_out; - - - char *remote_sdp_ip; - switch_port_t remote_sdp_port; - - char *local_sdp_ip; - switch_port_t local_sdp_port; - - char *adv_sdp_ip; - switch_port_t adv_sdp_port; - char *proxy_sdp_ip; - switch_port_t proxy_sdp_port; - int channels; - int adv_channels; - -} codec_params_t; struct media_helper { switch_core_session_t *session; @@ -106,6 +77,7 @@ struct media_helper { int up; }; + typedef struct switch_rtp_engine_s { switch_secure_settings_t ssec; switch_media_type_t type; @@ -130,12 +102,23 @@ typedef struct switch_rtp_engine_s { switch_port_t remote_rtcp_port; switch_rtp_bug_flag_t rtp_bugs; + + char *local_sdp_ip; + switch_port_t local_sdp_port; + char *adv_sdp_ip; + switch_port_t adv_sdp_port; + char *proxy_sdp_ip; + switch_port_t proxy_sdp_port; + + /** ZRTP **/ char *local_sdp_zrtp_hash; char *remote_sdp_zrtp_hash; + payload_map_t *cur_payload_map; + payload_map_t *payload_map; + payload_map_t *pmap_tail; - codec_params_t codec_params; uint32_t timestamp_send; char *cand_acl[SWITCH_MAX_CAND_ACL]; @@ -159,6 +142,8 @@ typedef struct switch_rtp_engine_s { switch_thread_t *media_thread; switch_mutex_t *read_mutex; + uint8_t reset_codec; + uint8_t codec_negotiated; } switch_rtp_engine_t; @@ -442,11 +427,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_co remote_host = switch_rtp_get_remote_host(a_engine->rtp_session); remote_port = switch_rtp_get_remote_port(a_engine->rtp_session); - a_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip); - a_engine->codec_params.remote_sdp_port = t38_options->remote_port; + a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip); + a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port; - if (remote_host && remote_port && !strcmp(remote_host, a_engine->codec_params.remote_sdp_ip) && - remote_port == a_engine->codec_params.remote_sdp_port) { + if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && + remote_port == a_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", switch_channel_get_name(session->channel)); @@ -456,13 +441,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_co switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n", switch_channel_get_name(session->channel), - remote_host, remote_port, a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port); + remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.remote_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->codec_params.remote_sdp_ip); + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip); switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); - if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->codec_params.remote_sdp_ip, - a_engine->codec_params.remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); } @@ -475,6 +460,81 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_co } +SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session, + switch_media_type_t type, + const char *name, + switch_sdp_type_t sdp_type, + uint32_t pt, + uint32_t rate, + uint32_t ptime, + uint8_t negotiated) +{ + payload_map_t *pmap; + int exists = 0; + switch_media_handle_t *smh; + switch_rtp_engine_t *engine; + + switch_assert(session); + + if (!(smh = session->media_handle)) { + return NULL; + } + + engine = &smh->engines[type]; + + switch_mutex_lock(smh->mutex); + + + for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { + exists = (!strcasecmp(name, pmap->iananame) && rate == pmap->rate && pmap->ptime == ptime); + + if (exists) { + break; + } + } + + + if (!exists) { + if (engine->payload_map && !engine->payload_map->allocated) { + pmap = engine->payload_map; + } else { + pmap = switch_core_alloc(session->pool, sizeof(*pmap)); + } + + pmap->sdp_type = sdp_type; + pmap->type = type; + pmap->iananame = switch_core_strdup(session->pool, name); + pmap->rm_encoding = pmap->iananame; + pmap->ptime = ptime; + pmap->rate = rate; + } + + pmap->allocated = 1; + pmap->recv_pt = pt; + + if (sdp_type == SDP_TYPE_REQUEST || !exists) { + pmap->pt = pt; + } + + if (negotiated) { + pmap->negotiated = negotiated; + } + + if (!exists) { + if (pmap == engine->payload_map) { + engine->pmap_tail = pmap; + } else if (!engine->payload_map) { + engine->payload_map = engine->pmap_tail = pmap; + } else { + engine->pmap_tail->next = pmap; + engine->pmap_tail = engine->pmap_tail->next; + } + } + + switch_mutex_unlock(smh->mutex); + + return pmap; +} @@ -1058,8 +1118,6 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t { switch_status_t status = SWITCH_STATUS_FALSE; switch_media_handle_t *smh = NULL; - - *smhp = NULL; if (zstr(params->sdp_username)) { @@ -1069,6 +1127,8 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t if ((session->media_handle = switch_core_session_alloc(session, (sizeof(*smh))))) { session->media_handle->session = session; + + *smhp = session->media_handle; switch_set_flag(session->media_handle, SMF_INIT); session->media_handle->media_flags[SCMF_RUNNING] = 1; @@ -1079,6 +1139,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t session->media_handle->mparams = params; + switch_mutex_init(&session->media_handle->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc = @@ -1087,6 +1148,12 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssrc = (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (uint32_t) time(NULL) / 2); + session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t)); + session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].payload_map; + session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map = switch_core_alloc(session->pool, sizeof(payload_map_t)); + session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].cur_payload_map = session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].payload_map; + + switch_channel_set_flag(session->channel, CF_DTLS_OK); status = SWITCH_STATUS_SUCCESS; @@ -1242,6 +1309,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session switch_rtp_engine_t *engine; switch_status_t status; switch_media_handle_t *smh; + int do_cng = 0; switch_assert(session); @@ -1299,6 +1367,85 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session goto end; } + /* re-set codec if necessary */ + if (engine->reset_codec > 0) { + const char *val; + int rtp_timeout_sec = 0; + int rtp_hold_timeout_sec = 0; + + engine->reset_codec = 0; + + if (switch_rtp_ready(engine->rtp_session)) { + if (switch_core_media_set_codec(session, 1, 0) != SWITCH_STATUS_SUCCESS) { + *frame = NULL; + switch_goto_status(SWITCH_STATUS_GENERR, end); + } + + if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) { + int v = atoi(val); + if (v >= 0) { + rtp_timeout_sec = v; + } + } + + if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) { + int v = atoi(val); + if (v >= 0) { + rtp_hold_timeout_sec = v; + } + } + + if (rtp_timeout_sec) { + engine->max_missed_packets = (engine->read_impl.samples_per_second * rtp_timeout_sec) / + engine->read_impl.samples_per_packet; + + switch_rtp_set_max_missed_packets(engine->rtp_session, engine->max_missed_packets); + if (!rtp_hold_timeout_sec) { + rtp_hold_timeout_sec = rtp_timeout_sec * 10; + } + } + + if (rtp_hold_timeout_sec) { + engine->max_missed_hold_packets = (engine->read_impl.samples_per_second * rtp_hold_timeout_sec) / + engine->read_impl.samples_per_packet; + } + } + + + if (session->read_resampler) { + switch_mutex_lock(session->resample_mutex); + switch_resample_destroy(&session->read_resampler); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n"); + switch_mutex_unlock(session->resample_mutex); + } + + if (session->write_resampler) { + switch_mutex_lock(session->resample_mutex); + switch_resample_destroy(&session->write_resampler); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n"); + switch_mutex_unlock(session->resample_mutex); + } + + switch_core_session_reset(session, 0, 0); + + + engine->check_frames = 0; + engine->last_ts = 0; + + switch_channel_audio_sync(session->channel); + do_cng = 1; + } + + if (do_cng) { + /* return CNG for now */ + *frame = &engine->read_frame; + switch_set_flag((*frame), SFF_CNG); + (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet; + memset((*frame)->data, 0, (*frame)->datalen); + switch_goto_status(SWITCH_STATUS_SUCCESS, end); + } + + /* Try to read an RTCP frame, if successful raise an event */ if (switch_rtcp_zerocopy_read_frame(engine->rtp_session, &rtcp_frame) == SWITCH_STATUS_SUCCESS) { switch_event_t *event; @@ -1381,22 +1528,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session switch_rtp_dequeue_dtmf(engine->rtp_session, &dtmf); switch_channel_queue_dtmf(session->channel, &dtmf); } - + if (engine->read_frame.datalen > 0) { uint32_t bytes = 0; int frames = 1; + /* autofix timing */ if (!switch_test_flag((&engine->read_frame), SFF_CNG)) { if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) { *frame = NULL; switch_goto_status(SWITCH_STATUS_GENERR, end); } + + /* check for timing issues */ + if (smh->media_flags[SCMF_AUTOFIX_TIMING] && engine->check_frames < MAX_CODEC_CHECK_FRAMES) { - /* check for timing or codec issues */ - if ((smh->media_flags[SCMF_AUTOFIX_TIMING] || smh->media_flags[SCMF_AUTOFIX_PT]) && - engine->check_frames < MAX_CODEC_CHECK_FRAMES) { - - int reset_codec = 0; engine->check_frames++; @@ -1404,62 +1550,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine->check_frames = MAX_CODEC_CHECK_FRAMES; goto skip; } - - /* autofix payload type */ - if (smh->media_flags[SCMF_AUTOFIX_PT] && - engine->read_frame.payload != smh->mparams->cng_pt && - engine->read_frame.payload != smh->mparams->recv_te && - engine->read_frame.payload != smh->mparams->te && - engine->read_frame.payload != engine->codec_params.recv_pt && - engine->read_frame.payload != engine->codec_params.agreed_pt && - engine->read_frame.payload != engine->codec_params.pt) { - - int i = 0; - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, - "Invalid payload received (received %d, expecting %d). " - "FS doesn't support multiple payload types in a single RTP session.\n", - (int) engine->read_frame.payload, (int) engine->codec_params.agreed_pt); - - /* search for payload type */ - for (i = 0; i < smh->mparams->num_codecs; i++) { - if (engine->read_frame.payload == smh->ianacodes[i]) { - const switch_codec_implementation_t *imp = smh->codecs[i]; - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, - "Changing current codec to %s (payload type %d).\n", - imp->iananame, (int) engine->read_frame.payload); - - engine->codec_params.iananame = switch_core_session_strdup(smh->session, imp->iananame); - engine->codec_params.pt = imp->ianacode; - engine->codec_params.agreed_pt = imp->ianacode; - engine->codec_params.recv_pt = imp->ianacode; - engine->codec_params.rm_encoding = switch_core_session_strdup(smh->session, imp->iananame); - engine->codec_params.rm_fmtp = NULL; - engine->codec_params.rm_rate = imp->samples_per_second; - engine->codec_params.adv_rm_rate = imp->samples_per_second; - if (strcasecmp(imp->iananame, "g722")) { - engine->codec_params.rm_rate = imp->actual_samples_per_second; - } - engine->codec_params.codec_ms = imp->microseconds_per_packet / 1000; - engine->codec_params.bitrate = imp->bits_per_second; - engine->codec_params.channels = 1; - - /* mark to re-set codec */ - reset_codec = 1; - break; - } - } - - if (!reset_codec) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, - "Could not change to payload type %d, ignoring...\n", - (int) engine->read_frame.payload); - } - - /* autofix timing */ - } else if (smh->media_flags[SCMF_AUTOFIX_TIMING] && (engine->read_frame.datalen % 10) == 0) { - + + if (smh->media_flags[SCMF_AUTOFIX_TIMING] && (engine->read_frame.datalen % 10) == 0) { + if (engine->last_ts && engine->read_frame.datalen != engine->read_impl.encoded_bytes_per_packet) { uint32_t codec_ms = (int) (engine->read_frame.timestamp - @@ -1478,7 +1571,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine->last_codec_ms = codec_ms; if (engine->mismatch_count > MAX_MISMATCH_FRAMES) { - if (codec_ms != engine->codec_params.codec_ms) { + if (codec_ms != engine->cur_payload_map->codec_ms) { if (codec_ms > 120) { /* yeah right */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, @@ -1491,20 +1584,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine->read_frame.datalen = 0; - if (codec_ms != engine->codec_params.codec_ms) { + if (codec_ms != engine->cur_payload_map->codec_ms) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Asynchronous PTIME not supported, changing our end from %d to %d\n", - (int) engine->codec_params.codec_ms, + (int) engine->cur_payload_map->codec_ms, (int) codec_ms ); switch_channel_set_variable_printf(session->channel, "rtp_h_X-Broken-PTIME", "Adv=%d;Sent=%d", - (int) engine->codec_params.codec_ms, (int) codec_ms); + (int) engine->cur_payload_map->codec_ms, (int) codec_ms); - engine->codec_params.codec_ms = codec_ms; + engine->cur_payload_map->codec_ms = codec_ms; /* mark to re-set codec */ - reset_codec = 2; + engine->reset_codec = 2; } } } @@ -1520,58 +1613,48 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine->mismatch_count = 0; engine->last_ts = 0; } + } - /* re-set codec if necessary */ - if (reset_codec > 0) { - const char *val; - int rtp_timeout_sec = 0; - int rtp_hold_timeout_sec = 0; + /* autofix payload type */ - if (switch_rtp_ready(engine->rtp_session)) { - if (switch_core_media_set_codec(session, 2, 0) != SWITCH_STATUS_SUCCESS) { - *frame = NULL; - switch_goto_status(SWITCH_STATUS_GENERR, end); - } + if (!engine->reset_codec && + engine->codec_negotiated && + engine->read_frame.payload != smh->mparams->cng_pt && + engine->read_frame.payload != smh->mparams->recv_te && + engine->read_frame.payload != smh->mparams->te && + engine->read_frame.payload != engine->cur_payload_map->recv_pt && + engine->read_frame.payload != engine->cur_payload_map->agreed_pt && + engine->read_frame.payload != engine->cur_payload_map->pt) { + + payload_map_t *pmap; + - if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) { - int v = atoi(val); - if (v >= 0) { - rtp_timeout_sec = v; - } - } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "alternate payload received (received %d, expecting %d)\n", + (int) engine->read_frame.payload, (int) engine->cur_payload_map->agreed_pt); - if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) { - int v = atoi(val); - if (v >= 0) { - rtp_hold_timeout_sec = v; - } - } - if (rtp_timeout_sec) { - engine->max_missed_packets = (engine->read_impl.samples_per_second * rtp_timeout_sec) / - engine->read_impl.samples_per_packet; + /* search for payload type */ + switch_mutex_lock(smh->mutex); + for (pmap = engine->cur_payload_map; pmap; pmap = pmap->next) { + if (engine->read_frame.payload == pmap->recv_pt) { + engine->cur_payload_map = pmap; - switch_rtp_set_max_missed_packets(engine->rtp_session, engine->max_missed_packets); - if (!rtp_hold_timeout_sec) { - rtp_hold_timeout_sec = rtp_timeout_sec * 10; - } - } - - if (rtp_hold_timeout_sec) { - engine->max_missed_hold_packets = (engine->read_impl.samples_per_second * rtp_hold_timeout_sec) / - engine->read_impl.samples_per_packet; - } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "Changing current codec to %s (payload type %d).\n", + pmap->iananame, pmap->pt); + + /* mark to re-set codec */ + engine->reset_codec = 1; + break; } - - engine->check_frames = 0; - engine->last_ts = 0; - - /* return CNG for now */ - *frame = &engine->read_frame; - switch_set_flag((*frame), SFF_CNG); - (*frame)->datalen = engine->read_impl.encoded_bytes_per_packet; - memset((*frame)->data, 0, (*frame)->datalen); - switch_goto_status(SWITCH_STATUS_SUCCESS, end); + } + switch_mutex_unlock(smh->mutex); + + if (!engine->reset_codec) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "Could not change to payload type %d, ignoring...\n", + (int) engine->read_frame.payload); } } @@ -1626,7 +1709,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio engine = &smh->engines[type]; - while (!(engine->read_codec.implementation && switch_rtp_ready(engine->rtp_session))) { if (switch_channel_ready(session->channel)) { switch_yield(10000); @@ -1736,7 +1818,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; - if (!v_engine->codec_params.rm_encoding) { + if (!v_engine->codec_negotiated) { return SWITCH_STATUS_FALSE; } @@ -1744,11 +1826,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se if (!force) { return SWITCH_STATUS_SUCCESS; } - if (strcasecmp(v_engine->read_codec.implementation->iananame, v_engine->codec_params.rm_encoding) || - v_engine->read_codec.implementation->samples_per_second != v_engine->codec_params.rm_rate) { + if (strcasecmp(v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding) || + v_engine->read_codec.implementation->samples_per_second != v_engine->cur_payload_map->rm_rate) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Changing Codec from %s to %s\n", - v_engine->read_codec.implementation->iananame, v_engine->codec_params.rm_encoding); + v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding); switch_core_codec_destroy(&v_engine->read_codec); switch_core_codec_destroy(&v_engine->write_codec); } else { @@ -1761,9 +1843,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se if (switch_core_codec_init(&v_engine->read_codec, - v_engine->codec_params.rm_encoding, - v_engine->codec_params.rm_fmtp, - v_engine->codec_params.rm_rate, + v_engine->cur_payload_map->rm_encoding, + v_engine->cur_payload_map->rm_fmtp, + v_engine->cur_payload_map->rm_rate, 0, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, @@ -1772,9 +1854,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se return SWITCH_STATUS_FALSE; } else { if (switch_core_codec_init(&v_engine->write_codec, - v_engine->codec_params.rm_encoding, - v_engine->codec_params.rm_fmtp, - v_engine->codec_params.rm_rate, + v_engine->cur_payload_map->rm_encoding, + v_engine->cur_payload_map->rm_fmtp, + v_engine->cur_payload_map->rm_rate, 0, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, @@ -1782,22 +1864,22 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n"); return SWITCH_STATUS_FALSE; } else { - v_engine->read_frame.rate = v_engine->codec_params.rm_rate; + v_engine->read_frame.rate = v_engine->cur_payload_map->rm_rate; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n", - switch_channel_get_name(session->channel), v_engine->codec_params.rm_encoding, - v_engine->codec_params.rm_rate, v_engine->codec_params.codec_ms); + switch_channel_get_name(session->channel), v_engine->cur_payload_map->rm_encoding, + v_engine->cur_payload_map->rm_rate, v_engine->cur_payload_map->codec_ms); v_engine->read_frame.codec = &v_engine->read_codec; v_engine->write_codec.fmtp_out = switch_core_session_strdup(session, v_engine->write_codec.fmtp_out); - v_engine->write_codec.agreed_pt = v_engine->codec_params.agreed_pt; - v_engine->read_codec.agreed_pt = v_engine->codec_params.agreed_pt; + v_engine->write_codec.agreed_pt = v_engine->cur_payload_map->agreed_pt; + v_engine->read_codec.agreed_pt = v_engine->cur_payload_map->agreed_pt; switch_core_session_set_video_read_codec(session, &v_engine->read_codec); switch_core_session_set_video_write_codec(session, &v_engine->write_codec); switch_channel_set_variable_printf(session->channel, "rtp_last_video_codec_string", "%s@%dh", - v_engine->codec_params.rm_encoding, v_engine->codec_params.rm_rate); + v_engine->cur_payload_map->rm_encoding, v_engine->cur_payload_map->rm_rate); if (switch_rtp_ready(v_engine->rtp_session)) { @@ -1806,25 +1888,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se msg.from = __FILE__; msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ; - switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt); + switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt); - if (v_engine->codec_params.recv_pt != v_engine->codec_params.agreed_pt) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s Set video receive payload to %u\n", switch_channel_get_name(session->channel), v_engine->codec_params.recv_pt); - - switch_rtp_set_recv_pt(v_engine->rtp_session, v_engine->codec_params.recv_pt); - } else { - switch_rtp_set_recv_pt(v_engine->rtp_session, v_engine->codec_params.agreed_pt); - } + //XX switch_core_session_receive_message(session, &msg); } - switch_channel_set_variable(session->channel, "rtp_use_video_codec_name", v_engine->codec_params.rm_encoding); - switch_channel_set_variable(session->channel, "rtp_use_video_codec_fmtp", v_engine->codec_params.rm_fmtp); - switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_rate", "%d", v_engine->codec_params.rm_rate); + switch_channel_set_variable(session->channel, "rtp_use_video_codec_name", v_engine->cur_payload_map->rm_encoding); + switch_channel_set_variable(session->channel, "rtp_use_video_codec_fmtp", v_engine->cur_payload_map->rm_fmtp); + switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_rate", "%d", v_engine->cur_payload_map->rm_rate); switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_ptime", "%d", 0); } @@ -1848,7 +1923,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ } a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; - if (!a_engine->codec_params.iananame) { + if (!a_engine->cur_payload_map->iananame) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No audio codec available\n"); switch_goto_status(SWITCH_STATUS_FALSE, end); } @@ -1857,9 +1932,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ if (!force) { switch_goto_status(SWITCH_STATUS_SUCCESS, end); } - if (strcasecmp(a_engine->read_impl.iananame, a_engine->codec_params.rm_encoding) || - (uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->codec_params.codec_ms || - a_engine->read_impl.samples_per_second != a_engine->codec_params.rm_rate ) { + if (strcasecmp(a_engine->read_impl.iananame, a_engine->cur_payload_map->iananame) || + (uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->cur_payload_map->codec_ms || + a_engine->read_impl.samples_per_second != a_engine->cur_payload_map->rm_rate ) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, @@ -1868,9 +1943,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ a_engine->read_impl.microseconds_per_packet / 1000, a_engine->read_impl.samples_per_second, - a_engine->codec_params.rm_encoding, - a_engine->codec_params.codec_ms, - a_engine->codec_params.rm_rate); + a_engine->cur_payload_map->iananame, + a_engine->cur_payload_map->codec_ms, + a_engine->cur_payload_map->rm_rate); switch_yield(a_engine->read_impl.microseconds_per_packet); switch_core_session_lock_codec_write(session); @@ -1887,12 +1962,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ } if (switch_core_codec_init_with_bitrate(&a_engine->read_codec, - a_engine->codec_params.iananame, - a_engine->codec_params.rm_fmtp, - a_engine->codec_params.rm_rate, - a_engine->codec_params.codec_ms, - a_engine->codec_params.channels, - a_engine->codec_params.bitrate, + a_engine->cur_payload_map->iananame, + a_engine->cur_payload_map->rm_fmtp, + a_engine->cur_payload_map->rm_rate, + a_engine->cur_payload_map->codec_ms, + a_engine->cur_payload_map->channels, + a_engine->cur_payload_map->bitrate, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | codec_flags, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -1904,12 +1979,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ if (switch_core_codec_init_with_bitrate(&a_engine->write_codec, - a_engine->codec_params.iananame, - a_engine->codec_params.rm_fmtp, - a_engine->codec_params.rm_rate, - a_engine->codec_params.codec_ms, - a_engine->codec_params.channels, - a_engine->codec_params.bitrate, + a_engine->cur_payload_map->iananame, + a_engine->cur_payload_map->rm_fmtp, + a_engine->cur_payload_map->rm_rate, + a_engine->cur_payload_map->codec_ms, + a_engine->cur_payload_map->channels, + a_engine->cur_payload_map->bitrate, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | codec_flags, NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -1919,12 +1994,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ a_engine->write_codec.session = session; - switch_channel_set_variable(session->channel, "rtp_use_codec_name", a_engine->codec_params.iananame); - switch_channel_set_variable(session->channel, "rtp_use_codec_fmtp", a_engine->codec_params.rm_fmtp); - switch_channel_set_variable_printf(session->channel, "rtp_use_codec_rate", "%d", a_engine->codec_params.rm_rate); - switch_channel_set_variable_printf(session->channel, "rtp_use_codec_ptime", "%d", a_engine->codec_params.codec_ms); + switch_channel_set_variable(session->channel, "rtp_use_codec_name", a_engine->cur_payload_map->iananame); + switch_channel_set_variable(session->channel, "rtp_use_codec_fmtp", a_engine->cur_payload_map->rm_fmtp); + switch_channel_set_variable_printf(session->channel, "rtp_use_codec_rate", "%d", a_engine->cur_payload_map->rm_rate); + switch_channel_set_variable_printf(session->channel, "rtp_use_codec_ptime", "%d", a_engine->cur_payload_map->codec_ms); switch_channel_set_variable_printf(session->channel, "rtp_last_audio_codec_string", "%s@%dh@%di", - a_engine->codec_params.iananame, a_engine->codec_params.rm_rate, a_engine->codec_params.codec_ms); + a_engine->cur_payload_map->iananame, a_engine->cur_payload_map->rm_rate, a_engine->cur_payload_map->codec_ms); switch_assert(a_engine->read_codec.implementation); switch_assert(a_engine->write_codec.implementation); @@ -1946,7 +2021,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ } } - a_engine->read_frame.rate = a_engine->codec_params.rm_rate; + a_engine->read_frame.rate = a_engine->cur_payload_map->rm_rate; if (!switch_core_codec_ready(&a_engine->read_codec)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n"); @@ -1954,34 +2029,32 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set Codec %s %s/%ld %d ms %d samples %d bits\n", - switch_channel_get_name(session->channel), a_engine->codec_params.iananame, a_engine->codec_params.rm_rate, - a_engine->codec_params.codec_ms, + switch_channel_get_name(session->channel), a_engine->cur_payload_map->iananame, a_engine->cur_payload_map->rm_rate, + a_engine->cur_payload_map->codec_ms, a_engine->read_impl.samples_per_packet, a_engine->read_impl.bits_per_second); a_engine->read_frame.codec = &a_engine->read_codec; - a_engine->write_codec.agreed_pt = a_engine->codec_params.agreed_pt; - a_engine->read_codec.agreed_pt = a_engine->codec_params.agreed_pt; + a_engine->write_codec.agreed_pt = a_engine->cur_payload_map->agreed_pt; + a_engine->read_codec.agreed_pt = a_engine->cur_payload_map->agreed_pt; if (force != 2) { switch_core_session_set_real_read_codec(session, &a_engine->read_codec); switch_core_session_set_write_codec(session, &a_engine->write_codec); } - a_engine->codec_params.fmtp_out = switch_core_session_strdup(session, a_engine->write_codec.fmtp_out); + a_engine->cur_payload_map->fmtp_out = switch_core_session_strdup(session, a_engine->write_codec.fmtp_out); if (switch_rtp_ready(a_engine->rtp_session)) { - switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->codec_params.pt); - switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->read_codec.agreed_pt); + switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->cur_payload_map->pt); } end: + if (resetting) { switch_core_session_unlock_codec_write(session); switch_core_session_unlock_codec_read(session); } - switch_core_media_set_video_codec(session, force); - return status; } @@ -2148,7 +2221,7 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ #ifdef RTCP_MUX } else if (!strcasecmp(attr->a_name, "rtcp-mux")) { engine->rtcp_mux = SWITCH_TRUE; - engine->remote_rtcp_port = engine->codec_params.remote_sdp_port; + engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port; got_rtcp_mux++; #endif } else if (!strcasecmp(attr->a_name, "candidate")) { @@ -2317,7 +2390,7 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ if (engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr && engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port) { char tmp[80] = ""; - engine->codec_params.remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr); + engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE, "setting remote %s ice addr to %s:%d based on candidate\n", type2str(type), engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port); @@ -2326,14 +2399,14 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ engine->remote_rtp_ice_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port; engine->remote_rtp_ice_addr = switch_core_session_strdup(smh->session, engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr); - engine->codec_params.remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr); - engine->codec_params.remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port; + engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr); + engine->cur_payload_map->remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port; if (engine->remote_rtcp_port) { - engine->remote_rtcp_port = engine->codec_params.remote_sdp_port; + engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port; } - switch_snprintf(tmp, sizeof(tmp), "%d", engine->codec_params.remote_sdp_port); - switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, engine->codec_params.remote_sdp_ip); + switch_snprintf(tmp, sizeof(tmp), "%d", engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, engine->cur_payload_map->remote_sdp_ip); switch_channel_set_variable(smh->session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); } @@ -2461,6 +2534,41 @@ SWITCH_DECLARE(void) switch_core_session_set_ice(switch_core_session_t *session) smh->mparams->rtcp_video_interval_msec = "10000"; } +#define MAX_MATCHES 30 +struct matches { + const switch_codec_implementation_t *imp; + sdp_rtpmap_t *map; + int rate; + int codec_idx; +}; + +static void greedy_sort(switch_media_handle_t *smh, struct matches *matches, int m_idx, const switch_codec_implementation_t **codec_array, int total_codecs) +{ + int j = 0, f = 0, g; + struct matches mtmp[MAX_MATCHES] = { { 0 } }; + for(j = 0; j < m_idx; j++) { + *&mtmp[j] = *&matches[j]; + } + for (g = 0; g < smh->mparams->num_codecs && g < total_codecs; g++) { + const switch_codec_implementation_t *imp = codec_array[g]; + + for(j = 0; j < m_idx; j++) { + if (mtmp[j].imp == imp) { + *&matches[f++] = *&mtmp[j]; + } + } + } +} + +static void clear_pmaps(switch_rtp_engine_t *engine) +{ + payload_map_t *pmap; + + for (pmap = engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { + pmap->negotiated = 0; + } +} + //? SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, switch_sdp_type_t sdp_type) { @@ -2468,10 +2576,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_payload_t best_te = 0, te = 0, cng_pt = 0; sdp_media_t *m; sdp_attribute_t *attr; - int first = 0, last = 0; int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0; int sendonly = 0, recvonly = 0; - int greedy = 0, x = 0, skip = 0, mine = 0; + int greedy = 0, x = 0, skip = 0; switch_channel_t *channel = switch_core_session_get_channel(session); const char *val; const char *crypto = NULL; @@ -2487,8 +2594,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s uint32_t near_rate = 0; const switch_codec_implementation_t *mimp = NULL, *near_match = NULL; sdp_rtpmap_t *mmap = NULL, *near_map = NULL; + struct matches matches[MAX_MATCHES] = { { 0 } }; + struct matches near_matches[MAX_MATCHES] = { { 0 } }; int codec_ms = 0; + uint32_t remote_codec_rate = 0, fmtp_remote_codec_rate = 0; const char *tmp; + int m_idx = 0; + int nm_idx = 0; switch_assert(session); @@ -2516,6 +2628,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_clear_flag(smh->session->channel, CF_DTLS); } + clear_pmaps(a_engine); + clear_pmaps(v_engine); + + if (proceed) *proceed = 1; greedy = !!switch_media_handle_test_media_flag(smh, SCMF_CODEC_GREEDY); @@ -2655,6 +2771,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, NULL); check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL); + for (m = sdp->sdp_media; m; m = m->m_next) { sdp_connection_t *connection; switch_core_session_t *other_session; @@ -2750,10 +2867,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_variable(other_channel, "t38_broken_boolean", "true"); } - a_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip); - a_engine->codec_params.remote_sdp_port = t38_options->remote_port; + a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip); + a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port; - if (remote_host && remote_port && !strcmp(remote_host, a_engine->codec_params.remote_sdp_ip) && remote_port == a_engine->codec_params.remote_sdp_port) { + if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && remote_port == a_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", switch_channel_get_name(session->channel)); } else { @@ -2761,14 +2878,14 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n", switch_channel_get_name(session->channel), - remote_host, remote_port, a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port); + remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.remote_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->codec_params.remote_sdp_ip); + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip); switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); - if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->codec_params.remote_sdp_ip, - a_engine->codec_params.remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); } @@ -2855,13 +2972,12 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s break; } - greed: x = 0; - if (a_engine->codec_params.rm_encoding && !(switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || + if (a_engine->cur_payload_map->rm_encoding && !(switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) { // && !switch_channel_test_flag(session->channel, CF_REINVITE)) { - char *remote_host = a_engine->codec_params.remote_sdp_ip; - switch_port_t remote_port = a_engine->codec_params.remote_sdp_port; + char *remote_host = a_engine->cur_payload_map->remote_sdp_ip; + switch_port_t remote_port = a_engine->cur_payload_map->remote_sdp_port; int same = 0; if (switch_rtp_ready(a_engine->rtp_session)) { @@ -2871,9 +2987,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s for (map = m->m_rtpmaps; map; map = map->rm_next) { if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { - match = (map->rm_pt == a_engine->codec_params.pt) ? 1 : 0; + match = (map->rm_pt == a_engine->cur_payload_map->pt) ? 1 : 0; } else { - match = strcasecmp(switch_str_nil(map->rm_encoding), a_engine->codec_params.iananame) ? 0 : 1; + match = strcasecmp(switch_str_nil(map->rm_encoding), a_engine->cur_payload_map->iananame) ? 0 : 1; } if (match && connection->c_address && remote_host && !strcmp(connection->c_address, remote_host) && m->m_port == remote_port) { @@ -2887,7 +3003,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (same) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Our existing sdp is still good [%s %s:%d], let's keep it.\n", - a_engine->codec_params.rm_encoding, a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port); + a_engine->cur_payload_map->rm_encoding, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); got_audio = 1; } else { match = 0; @@ -2896,17 +3012,22 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } for (map = m->m_rtpmaps; map; map = map->rm_next) { + int32_t i; const char *rm_encoding; - + uint32_t map_bit_rate = 0; + switch_codec_fmtp_t codec_fmtp = { 0 }; + if (!(rm_encoding = map->rm_encoding)) { rm_encoding = ""; } - - + + if (!strcasecmp(rm_encoding, "telephone-event")) { - if (!best_te || map->rm_rate == a_engine->codec_params.rm_rate) { + if (!best_te || map->rm_rate == a_engine->cur_payload_map->rm_rate) { best_te = (switch_payload_t) map->rm_pt; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set telephone-event payload to %u\n", best_te); } + continue; } if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && !cng_pt && !strcasecmp(rm_encoding, "CN")) { @@ -2915,36 +3036,18 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set comfort noise payload to %u\n", cng_pt); switch_rtp_set_cng_pt(a_engine->rtp_session, smh->mparams->cng_pt); } + continue; } - - } - - for (map = m->m_rtpmaps; map; map = map->rm_next) { - int32_t i; - const char *rm_encoding; - uint32_t map_bit_rate = 0; - switch_codec_fmtp_t codec_fmtp = { 0 }; - + + if (x++ < skip) { continue; } - if (!(rm_encoding = map->rm_encoding)) { - rm_encoding = ""; - } - if (match) { continue; } - if (greedy) { - first = mine; - last = first + 1; - } else { - first = 0; - last = smh->mparams->num_codecs; - } - codec_ms = ptime; if (maxptime && (!codec_ms || codec_ms > maxptime)) { @@ -2961,6 +3064,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s codec_ms = 30; } + remote_codec_rate = map->rm_rate; + fmtp_remote_codec_rate = 0; + memset(&codec_fmtp, 0, sizeof(codec_fmtp)); + if (zstr(map->rm_fmtp)) { if (!strcasecmp(map->rm_encoding, "ilbc")) { codec_ms = 30; @@ -2977,27 +3084,32 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (codec_fmtp.microseconds_per_packet) { codec_ms = (codec_fmtp.microseconds_per_packet / 1000); } + if (codec_fmtp.actual_samples_per_second) { + fmtp_remote_codec_rate = codec_fmtp.actual_samples_per_second; + } } } - - for (i = first; i < last && i < total_codecs; i++) { + for (i = 0; i < smh->mparams->num_codecs && i < total_codecs; i++) { const switch_codec_implementation_t *imp = codec_array[i]; uint32_t bit_rate = imp->bits_per_second; uint32_t codec_rate = imp->samples_per_second; - char *samp = NULL; if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO) { continue; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio Codec Compare [%s:%d:%u:%d:%u]/[%s:%d:%u:%d:%u]\n", - rm_encoding, map->rm_pt, (int) map->rm_rate, codec_ms, map_bit_rate, + rm_encoding, map->rm_pt, (int) remote_codec_rate, codec_ms, map_bit_rate, imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate); if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { match = (map->rm_pt == imp->ianacode) ? 1 : 0; } else { - match = (!strcasecmp(rm_encoding, imp->iananame) && (map->rm_rate == codec_rate)) ? 1 : 0; + match = (!strcasecmp(rm_encoding, imp->iananame) && + (remote_codec_rate == codec_rate || fmtp_remote_codec_rate == imp->actual_samples_per_second)) ? 1 : 0; + if (fmtp_remote_codec_rate) { + remote_codec_rate = fmtp_remote_codec_rate; + } } if (match && bit_rate && map_bit_rate && map_bit_rate != bit_rate && strcasecmp(map->rm_encoding, "ilbc") && @@ -3006,155 +3118,190 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s match = 0; } - if (match && map->rm_rate && codec_rate && map->rm_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") || + if (match && remote_codec_rate && codec_rate && remote_codec_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") || !strcasecmp(map->rm_encoding, "pcmu"))) { /* if the sampling rate is specified and doesn't match, this is not a codec match for G.711 */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sampling rates have to match for G.711\n"); match = 0; } - if (!zstr(map->rm_fmtp)) { - samp = strstr(map->rm_fmtp, "samplerate="); - } - if (!strcasecmp(map->rm_encoding, "opus") && !strcasecmp(rm_encoding, imp->iananame) && samp) { - char *rate_str = samp + 11; - - if (rate_str && *rate_str) { - near_rate = atoi(rate_str); - near_match = imp; - near_map = mmap = map; - match = 0; - goto near_match; - } - } - if (match) { if (scrooge) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bah HUMBUG! Sticking with %s@%uh@%ui\n", imp->iananame, imp->samples_per_second, imp->microseconds_per_packet / 1000); - } else if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || map->rm_rate != codec_rate) { + } else if ((ptime && codec_ms && codec_ms * 1000 != imp->microseconds_per_packet) || remote_codec_rate != codec_rate) { /* ptime does not match */ match = 0; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "Audio Codec Compare [%s:%d:%u:%d:%u] is saved as a near-match\n", + imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate); - /* save first near_match */ - if (!near_match) { - near_rate = map->rm_rate; - near_match = imp; - near_map = mmap = map; + near_matches[nm_idx].codec_idx = i; + near_matches[nm_idx].rate = remote_codec_rate; + near_matches[nm_idx].imp = imp; + near_matches[nm_idx].map = map; + nm_idx++; - if (switch_true(switch_channel_get_variable_dup(channel, "rtp_negotiate_near_match", SWITCH_FALSE, -1))) { - goto near_match; - } - } continue; } - mimp = imp; - mmap = map; - break; + + matches[m_idx].codec_idx = i; + matches[m_idx].rate = codec_rate; + matches[m_idx].imp = imp; + matches[m_idx].map = map; + m_idx++; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "Audio Codec Compare [%s:%d:%u:%d:%u] ++++ is saved as a match\n", + imp->iananame, imp->ianacode, codec_rate, imp->microseconds_per_packet / 1000, bit_rate); + + if (m_idx >= MAX_MATCHES) { + break; + } + + match = 0; } } - - if (!match && greedy) { - skip++; - continue; - } - - if (match && mimp) { + if (m_idx >= MAX_MATCHES) { break; } } - near_match: + if (!m_idx && nm_idx) { + int j; - if (!match && near_match) { - const switch_codec_implementation_t *search[1]; - char *prefs[1]; - char tmp[80]; - int num; + for(j = 0; j < nm_idx; j++) { + const switch_codec_implementation_t *search[1]; + char *prefs[1]; + char tmp[80]; + int num; + const switch_codec_implementation_t *timp = NULL; + + near_rate = near_matches[j].rate; + near_match = near_matches[j].imp; + near_map = near_matches[j].map; + + switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second, + codec_ms); + + prefs[0] = tmp; + num = switch_loadable_module_get_codecs_sorted(search, 1, prefs, 1); - switch_snprintf(tmp, sizeof(tmp), "%s@%uh@%ui", near_match->iananame, near_rate ? near_rate : near_match->samples_per_second, - codec_ms); + if (num) { + timp = search[0]; + } else { + timp = near_match; + } - prefs[0] = tmp; - num = switch_loadable_module_get_codecs_sorted(search, 1, prefs, 1); - - if (num) { - mimp = search[0]; - } else { - mimp = near_match; - } - - if (!maxptime || mimp->microseconds_per_packet / 1000 <= maxptime) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Substituting codec %s@%ui@%uh\n", - mimp->iananame, mimp->microseconds_per_packet / 1000, mimp->samples_per_second); - mmap = near_map; - match = 1; - } else { - mimp = NULL; - mmap = NULL; - match = 0; + if (!maxptime || timp->microseconds_per_packet / 1000 <= maxptime) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Substituting codec %s@%ui@%uh\n", + timp->iananame, timp->microseconds_per_packet / 1000, timp->actual_samples_per_second); + match = 1; + + matches[m_idx].codec_idx = near_matches[j].codec_idx; + matches[m_idx].rate = near_rate; + matches[m_idx].imp = timp; + matches[m_idx].map = near_map; + m_idx++; + + break; + } } } - if (mimp && mmap) { - char tmp[50]; - const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload"); + if (m_idx) { + int j; - a_engine->codec_params.rm_encoding = switch_core_session_strdup(session, (char *) mmap->rm_encoding); - a_engine->codec_params.iananame = switch_core_session_strdup(session, (char *) mimp->iananame); - a_engine->codec_params.pt = (switch_payload_t) mmap->rm_pt; - a_engine->codec_params.rm_rate = mimp->samples_per_second; - a_engine->codec_params.adv_rm_rate = mimp->samples_per_second; - if (strcasecmp(mimp->iananame, "g722")) { - a_engine->codec_params.rm_rate = mimp->actual_samples_per_second; - } - a_engine->codec_params.codec_ms = mimp->microseconds_per_packet / 1000; - a_engine->codec_params.bitrate = mimp->bits_per_second; - a_engine->codec_params.channels = mmap->rm_params ? atoi(mmap->rm_params) : 1; - - if (!strcasecmp((char *) mmap->rm_encoding, "opus")) { - if (a_engine->codec_params.channels == 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid SDP for opus. Don't ask.. but it needs a /2\n"); - a_engine->codec_params.adv_channels = 1; - } else { - a_engine->codec_params.adv_channels = 2; /* IKR ???*/ - } - if (!zstr((char *) mmap->rm_fmtp) && switch_stristr("stereo=1", (char *) mmap->rm_fmtp)) { - a_engine->codec_params.channels = 2; - } else { - a_engine->codec_params.channels = 1; - } - } else { - a_engine->codec_params.adv_channels = a_engine->codec_params.channels; + if (greedy) { /* sort in favor of mine */ + greedy_sort(smh, matches, m_idx, codec_array, total_codecs); } - a_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address); - a_engine->codec_params.remote_sdp_port = (switch_port_t) m->m_port; - a_engine->codec_params.rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp); + match = 1; + a_engine->codec_negotiated = 1; - a_engine->codec_params.agreed_pt = (switch_payload_t) mmap->rm_pt; - smh->num_negotiated_codecs = 0; - smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp; - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.remote_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->codec_params.remote_sdp_ip); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); - a_engine->codec_params.recv_pt = (switch_payload_t)mmap->rm_pt; - - if (!switch_true(mirror) && - switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && - (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) { - switch_core_media_get_offered_pt(session, mimp, &a_engine->codec_params.recv_pt); + for(j = 0; j < m_idx; j++) { + payload_map_t *pmap = switch_core_media_add_payload_map(session, + SWITCH_MEDIA_TYPE_AUDIO, + matches[j].map->rm_encoding, + sdp_type, + matches[j].map->rm_pt, + matches[j].imp->samples_per_second, + matches[j].imp->microseconds_per_packet / 1000, + SWITCH_TRUE); + mimp = matches[j].imp; + mmap = matches[j].map; + + if (j == 0) { + a_engine->cur_payload_map = pmap; + } + + pmap->rm_encoding = switch_core_session_strdup(session, (char *) mmap->rm_encoding); + pmap->iananame = switch_core_session_strdup(session, (char *) mimp->iananame); + pmap->pt = (switch_payload_t) mmap->rm_pt; + pmap->rm_rate = mimp->samples_per_second; + pmap->adv_rm_rate = mimp->samples_per_second; + if (strcasecmp(mimp->iananame, "g722")) { + pmap->rm_rate = mimp->actual_samples_per_second; + } + pmap->codec_ms = mimp->microseconds_per_packet / 1000; + pmap->bitrate = mimp->bits_per_second; + pmap->channels = mmap->rm_params ? atoi(mmap->rm_params) : 1; + + if (!strcasecmp((char *) mmap->rm_encoding, "opus")) { + if (pmap->channels == 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid SDP for opus. Don't ask.. but it needs a /2\n"); + pmap->adv_channels = 1; + } else { + pmap->adv_channels = 2; /* IKR ???*/ + } + if (!zstr((char *) mmap->rm_fmtp) && switch_stristr("stereo=1", (char *) mmap->rm_fmtp)) { + pmap->channels = 2; + } else { + pmap->channels = 1; + } + } else { + pmap->adv_channels = pmap->channels; + } + + pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address); + pmap->remote_sdp_port = (switch_port_t) m->m_port; + pmap->rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp); + + pmap->agreed_pt = (switch_payload_t) mmap->rm_pt; + smh->num_negotiated_codecs = 0; + smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp; + pmap->recv_pt = (switch_payload_t)mmap->rm_pt; + } - - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.recv_pt); - switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp); - } if (match) { - if (switch_core_media_set_codec(session, 1, smh->mparams->codec_flags) == SWITCH_STATUS_SUCCESS) { + char tmp[50]; + const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload"); + + + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); + + + if (!switch_true(mirror) && + switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && + (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) { + switch_core_media_get_offered_pt(session, mimp, &a_engine->cur_payload_map->recv_pt); + } + + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt); + switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp); + + if (switch_core_codec_ready(&a_engine->read_codec)) { + a_engine->reset_codec = 1; + } + + if (switch_core_media_set_codec(session, 0, smh->mparams->codec_flags) == SWITCH_STATUS_SUCCESS) { got_audio = 1; check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, m); } else { @@ -3205,25 +3352,24 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } } - - if (!match && greedy && mine < total_codecs) { - mine++; - skip = 0; - goto greed; - } - } else if (m->m_type == sdp_media_video && m->m_port) { sdp_rtpmap_t *map; const char *rm_encoding; const switch_codec_implementation_t *mimp = NULL; int vmatch = 0, i; + + nm_idx = 0; + m_idx = 0; + memset(matches, 0, sizeof(matches[0]) * MAX_MATCHES); + memset(near_matches, 0, sizeof(near_matches[0]) * MAX_MATCHES); + switch_channel_set_variable(session->channel, "video_possible", "true"); connection = sdp->sdp_connection; if (m->m_connections) { connection = m->m_connections; } - + if (!connection) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n"); match = 0; @@ -3239,7 +3385,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } } } - + for (attr = m->m_attributes; attr; attr = attr->a_next) { if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) { //framerate = atoi(attr->a_value); @@ -3289,7 +3435,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_test_flag(session->channel, CF_NOVIDEO)) { continue; } - + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n", rm_encoding, map->rm_pt, imp->iananame, imp->ianacode); if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { @@ -3300,56 +3446,89 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (vmatch && (map->rm_rate == imp->samples_per_second)) { - mimp = imp; - break; - } else { - vmatch = 0; + matches[m_idx].imp = imp; + matches[m_idx].map = map; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] is saved as a match\n", + imp->iananame, imp->ianacode); + m_idx++; } - } - if (mimp) { - if ((v_engine->codec_params.rm_encoding = switch_core_session_strdup(session, (char *) rm_encoding))) { - char tmp[50]; - const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_video_codec_payload"); - - v_engine->codec_params.pt = (switch_payload_t) map->rm_pt; - v_engine->codec_params.rm_rate = map->rm_rate; - v_engine->codec_params.codec_ms = mimp->microseconds_per_packet / 1000; - - - v_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address); - v_engine->codec_params.remote_sdp_port = (switch_port_t) m->m_port; - - v_engine->codec_params.rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp); - - v_engine->codec_params.agreed_pt = (switch_payload_t) map->rm_pt; - switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->codec_params.remote_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE, v_engine->codec_params.remote_sdp_ip); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE, tmp); - switch_channel_set_variable(session->channel, "rtp_video_fmtp", v_engine->codec_params.rm_fmtp); - switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->codec_params.agreed_pt); - switch_channel_set_variable(session->channel, "rtp_video_pt", tmp); - switch_core_media_check_video_codecs(session); - - v_engine->codec_params.recv_pt = (switch_payload_t)map->rm_pt; - - if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - switch_core_media_get_offered_pt(session, mimp, &v_engine->codec_params.recv_pt); - } - - switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->codec_params.recv_pt); - switch_channel_set_variable(session->channel, "rtp_video_recv_pt", tmp); - if (!match && vmatch) match = 1; - - check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, m); - //check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL); - break; - } else { - vmatch = 0; - } + vmatch = 0; } } - + + if (m_idx) { + char tmp[50]; + const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_video_codec_payload"); + int j = 0; + + if (greedy) { /* sort in favor of mine */ + greedy_sort(smh, matches, m_idx, codec_array, total_codecs); + } + + vmatch = 1; + v_engine->codec_negotiated = 1; + + for(j = 0; j < m_idx; j++) { + payload_map_t *pmap = switch_core_media_add_payload_map(session, + SWITCH_MEDIA_TYPE_VIDEO, + matches[j].map->rm_encoding, + sdp_type, + matches[j].map->rm_pt, + matches[j].imp->samples_per_second, + matches[j].imp->microseconds_per_packet / 1000, + SWITCH_TRUE); + + if (j == 0) { + v_engine->cur_payload_map = pmap; + } + + mimp = matches[j].imp; + map = matches[j].map; + + pmap->rm_encoding = switch_core_session_strdup(session, (char *) map->rm_encoding); + pmap->pt = (switch_payload_t) map->rm_pt; + pmap->rm_rate = map->rm_rate; + pmap->codec_ms = mimp->microseconds_per_packet / 1000; + + + pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address); + pmap->remote_sdp_port = (switch_port_t) m->m_port; + + pmap->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp); + + pmap->agreed_pt = (switch_payload_t) map->rm_pt; + + pmap->recv_pt = (switch_payload_t)map->rm_pt; + + if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + switch_core_media_get_offered_pt(session, mimp, &pmap->recv_pt); + } + } + + + + switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE, v_engine->cur_payload_map->remote_sdp_ip); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE, tmp); + switch_channel_set_variable(session->channel, "rtp_video_fmtp", v_engine->cur_payload_map->rm_fmtp); + switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->agreed_pt); + switch_channel_set_variable(session->channel, "rtp_video_pt", tmp); + switch_core_media_check_video_codecs(session); + switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->recv_pt); + switch_channel_set_variable(session->channel, "rtp_video_recv_pt", tmp); + if (!match && vmatch) match = 1; + + if (switch_core_codec_ready(&v_engine->read_codec)) { + v_engine->reset_codec = 1; + } + + if (switch_core_media_set_video_codec(session, 0) == SWITCH_STATUS_SUCCESS) { + check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, m); + } + + } } } @@ -3596,7 +3775,7 @@ static switch_status_t start_video_thread(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "%s Starting Video thread\n", switch_core_session_get_name(session)); - switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt); + switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt); v_engine->mh.session = session; switch_threadattr_create(&thd_attr, pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); @@ -3703,20 +3882,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ goto end; } - a_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, rip); - a_engine->codec_params.remote_sdp_port = (switch_port_t) atoi(rp); + a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, rip); + a_engine->cur_payload_map->remote_sdp_port = (switch_port_t) atoi(rp); if (*rvp) { - v_engine->codec_params.remote_sdp_ip = switch_core_session_strdup(session, rip); - v_engine->codec_params.remote_sdp_port = (switch_port_t) atoi(rvp); + v_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, rip); + v_engine->cur_payload_map->remote_sdp_port = (switch_port_t) atoi(rvp); switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); switch_channel_set_flag(session->channel, CF_VIDEO); } - if (v_engine->codec_params.remote_sdp_ip && v_engine->codec_params.remote_sdp_port) { - if (!strcmp(v_engine->codec_params.remote_sdp_ip, rip) && atoi(rvp) == v_engine->codec_params.remote_sdp_port) { + if (v_engine->cur_payload_map->remote_sdp_ip && v_engine->cur_payload_map->remote_sdp_port) { + if (!strcmp(v_engine->cur_payload_map->remote_sdp_ip, rip) && atoi(rvp) == v_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote video address:port [%s:%d] has not changed.\n", - v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port); + v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port); } else { switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); switch_channel_set_flag(session->channel, CF_VIDEO); @@ -3731,12 +3910,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ } - if (switch_rtp_set_remote_address(v_engine->rtp_session, v_engine->codec_params.remote_sdp_ip, - v_engine->codec_params.remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + if (switch_rtp_set_remote_address(v_engine->rtp_session, v_engine->cur_payload_map->remote_sdp_ip, + v_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n", - v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port); + v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port); if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_PROXY_MODE) && !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) && !switch_channel_test_flag(session->channel, CF_WEBRTC)) { @@ -3745,7 +3924,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ start_video_thread(session); } - if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING) || switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_PT)) { + if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) { v_engine->check_frames = 0; } } @@ -3759,9 +3938,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ const char *rport = NULL; switch_port_t remote_rtcp_port = 0; - if (remote_host && remote_port && !strcmp(remote_host, a_engine->codec_params.remote_sdp_ip) && remote_port == a_engine->codec_params.remote_sdp_port) { + if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && remote_port == a_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n", - a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port); + a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); switch_goto_status(SWITCH_STATUS_BREAK, end); } @@ -3770,20 +3949,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_ } - if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->codec_params.remote_sdp_ip, - a_engine->codec_params.remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); status = SWITCH_STATUS_GENERR; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n", - a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port); + a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) && !switch_channel_test_flag(session->channel, CF_WEBRTC)) { /* Reactivate the NAT buster flag. */ switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } - if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING) || switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_PT)) { + if (switch_media_handle_test_media_flag(smh, SCMF_AUTOFIX_TIMING)) { a_engine->check_frames = 0; } status = SWITCH_STATUS_SUCCESS; @@ -3930,31 +4109,31 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio /* Don't do anything if we're in proxy mode or if a (remote) port already has been found */ if (!force) { if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || - switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || engine->codec_params.adv_sdp_port) { + switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) || engine->adv_sdp_port) { return SWITCH_STATUS_SUCCESS; } } /* Release the local sdp port */ - if (engine->codec_params.local_sdp_port) { - switch_rtp_release_port(smh->mparams->rtpip, engine->codec_params.local_sdp_port); + if (engine->local_sdp_port) { + switch_rtp_release_port(smh->mparams->rtpip, engine->local_sdp_port); } /* Request a local port from the core's allocator */ - if (!(engine->codec_params.local_sdp_port = switch_rtp_request_port(smh->mparams->rtpip))) { + if (!(engine->local_sdp_port = switch_rtp_request_port(smh->mparams->rtpip))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "No %s RTP ports available!\n", tstr); return SWITCH_STATUS_FALSE; } - engine->codec_params.local_sdp_ip = smh->mparams->rtpip; + engine->local_sdp_ip = smh->mparams->rtpip; - sdp_port = engine->codec_params.local_sdp_port; + sdp_port = engine->local_sdp_port; /* Check if NAT is detected */ if (!zstr(smh->mparams->remote_ip) && switch_core_media_check_nat(smh, smh->mparams->remote_ip)) { /* Yes, map the port through switch_nat */ - switch_nat_add_mapping(engine->codec_params.local_sdp_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); + switch_nat_add_mapping(engine->local_sdp_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); switch_snprintf(vname, sizeof(vname), "rtp_adv_%s_ip", tstr); @@ -3981,16 +4160,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio use_ip = smh->mparams->rtpip; } - engine->codec_params.adv_sdp_port = sdp_port; - engine->codec_params.adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip); + engine->adv_sdp_port = sdp_port; + engine->adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip); if (type == SWITCH_MEDIA_TYPE_AUDIO) { - switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, engine->codec_params.local_sdp_ip); + switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, engine->local_sdp_ip); switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, "%d", sdp_port); - switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, engine->codec_params.adv_sdp_ip); + switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, engine->adv_sdp_ip); } else { - switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, engine->codec_params.adv_sdp_ip); + switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, engine->adv_sdp_ip); switch_channel_set_variable_printf(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, "%d", sdp_port); } @@ -4041,28 +4220,28 @@ SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *ses if (v_engine->rtp_session) { switch_rtp_destroy(&v_engine->rtp_session); - } else if (v_engine->codec_params.local_sdp_port) { - switch_rtp_release_port(smh->mparams->rtpip, v_engine->codec_params.local_sdp_port); + } else if (v_engine->local_sdp_port) { + switch_rtp_release_port(smh->mparams->rtpip, v_engine->local_sdp_port); } - if (v_engine->codec_params.local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && + if (v_engine->local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && switch_core_media_check_nat(smh, smh->mparams->remote_ip)) { - switch_nat_del_mapping((switch_port_t) v_engine->codec_params.local_sdp_port, SWITCH_NAT_UDP); - switch_nat_del_mapping((switch_port_t) v_engine->codec_params.local_sdp_port + 1, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) v_engine->local_sdp_port, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) v_engine->local_sdp_port + 1, SWITCH_NAT_UDP); } if (a_engine->rtp_session) { switch_rtp_destroy(&a_engine->rtp_session); - } else if (a_engine->codec_params.local_sdp_port) { - switch_rtp_release_port(smh->mparams->rtpip, a_engine->codec_params.local_sdp_port); + } else if (a_engine->local_sdp_port) { + switch_rtp_release_port(smh->mparams->rtpip, a_engine->local_sdp_port); } - if (a_engine->codec_params.local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && + if (a_engine->local_sdp_port > 0 && !zstr(smh->mparams->remote_ip) && switch_core_media_check_nat(smh, smh->mparams->remote_ip)) { - switch_nat_del_mapping((switch_port_t) a_engine->codec_params.local_sdp_port, SWITCH_NAT_UDP); - switch_nat_del_mapping((switch_port_t) a_engine->codec_params.local_sdp_port + 1, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) a_engine->local_sdp_port, SWITCH_NAT_UDP); + switch_nat_del_mapping((switch_port_t) a_engine->local_sdp_port + 1, SWITCH_NAT_UDP); } } @@ -4199,7 +4378,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_media_handle_t *smh; switch_assert(session); - + if (!(smh = session->media_handle)) { return SWITCH_STATUS_FALSE; } @@ -4241,6 +4420,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi goto end; } + switch_core_media_set_video_codec(session, 0); + + memset(flags, 0, sizeof(flags)); flags[SWITCH_RTP_FLAG_DATAWAIT]++; @@ -4287,32 +4469,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session); switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session); - if (remote_host && remote_port && !strcmp(remote_host, a_engine->codec_params.remote_sdp_ip) && remote_port == a_engine->codec_params.remote_sdp_port) { + if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && + remote_port == a_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n", switch_channel_get_name(session->channel)); - if (switch_rtp_ready(a_engine->rtp_session)) { - if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s Set audio receive payload in Re-INVITE for non-matching dynamic PT to %u\n", - switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt); - - switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.recv_pt); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s Setting audio receive payload in Re-INVITE to %u\n", - switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt); - switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.agreed_pt); - } - - } + //XX goto video; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n", switch_channel_get_name(session->channel), - remote_host, remote_port, a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port); + remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.remote_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->codec_params.remote_sdp_ip); + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip); switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); } } @@ -4320,30 +4489,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (!switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n", switch_channel_get_name(session->channel), - a_engine->codec_params.local_sdp_ip, - a_engine->codec_params.local_sdp_port, - a_engine->codec_params.remote_sdp_ip, - a_engine->codec_params.remote_sdp_port, a_engine->codec_params.agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000); + a_engine->local_sdp_ip, + a_engine->local_sdp_port, + a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, a_engine->cur_payload_map->agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000); - if (switch_rtp_ready(a_engine->rtp_session)) { - switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->codec_params.agreed_pt); - - if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s Set audio receive payload to %u\n", switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt); - - switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.recv_pt); - } else { - switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.agreed_pt); - } - - } + //XX } - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.local_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, a_engine->codec_params.local_sdp_ip); + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->local_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE, a_engine->local_sdp_ip); switch_channel_set_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp); - switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, a_engine->codec_params.adv_sdp_ip); + switch_channel_set_variable(session->channel, SWITCH_ADVERTISED_MEDIA_IP_VARIABLE, a_engine->adv_sdp_ip); if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) { const char *rport = NULL; @@ -4355,14 +4512,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } } - if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port, + if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n", - a_engine->codec_params.remote_sdp_ip, a_engine->codec_params.remote_sdp_port); + a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); - if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->codec_params.remote_sdp_ip, "0.0.0.0")) { + if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")) { switch_core_media_toggle_hold(session, 0); } @@ -4398,13 +4555,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "PROXY AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n", switch_channel_get_name(session->channel), - a_engine->codec_params.remote_sdp_ip, - a_engine->codec_params.remote_sdp_port, - a_engine->codec_params.remote_sdp_ip, - a_engine->codec_params.remote_sdp_port, a_engine->codec_params.agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000); + a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, + a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, a_engine->cur_payload_map->agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000); if (switch_rtp_ready(a_engine->rtp_session)) { - switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->codec_params.agreed_pt); + switch_rtp_set_default_payload(a_engine->rtp_session, a_engine->cur_payload_map->agreed_pt); } } else { @@ -4416,14 +4573,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } if (switch_channel_up(session->channel)) { - a_engine->rtp_session = switch_rtp_new(a_engine->codec_params.local_sdp_ip, - a_engine->codec_params.local_sdp_port, - a_engine->codec_params.remote_sdp_ip, - a_engine->codec_params.remote_sdp_port, - a_engine->codec_params.agreed_pt, + + a_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip, + a_engine->local_sdp_port, + a_engine->cur_payload_map->remote_sdp_ip, + a_engine->cur_payload_map->remote_sdp_port, + a_engine->cur_payload_map->agreed_pt, a_engine->read_impl.samples_per_packet, - a_engine->codec_params.codec_ms * 1000, + a_engine->cur_payload_map->codec_ms * 1000, flags, timer_name, &err, switch_core_session_get_pool(session)); + + if (switch_rtp_ready(a_engine->rtp_session)) { + switch_rtp_set_payload_map(a_engine->rtp_session, &a_engine->payload_map); + } } if (switch_rtp_ready(a_engine->rtp_session)) { @@ -4450,7 +4612,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_channel_set_flag(session->channel, CF_FS_RTP); - switch_channel_set_variable_printf(session->channel, "rtp_use_pt", "%d", a_engine->codec_params.agreed_pt); + switch_channel_set_variable_printf(session->channel, "rtp_use_pt", "%d", a_engine->cur_payload_map->agreed_pt); if ((val = switch_channel_get_variable(session->channel, "rtp_enable_vad_in")) && switch_true(val)) { vad_in = 1; @@ -4680,12 +4842,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_channel_set_variable_printf(session->channel, "rtp_2833_recv_payload", "%d", smh->mparams->recv_te); } - if (a_engine->codec_params.recv_pt != a_engine->codec_params.agreed_pt) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s Set audio receive payload to %u\n", switch_channel_get_name(session->channel), a_engine->codec_params.recv_pt); - - switch_rtp_set_recv_pt(a_engine->rtp_session, a_engine->codec_params.recv_pt); - } + //XX if (switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) || ((val = switch_channel_get_variable(session->channel, "supress_cng")) && switch_true(val)) || @@ -4714,8 +4871,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_core_session_apply_crypto(session, SWITCH_MEDIA_TYPE_AUDIO); - switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->codec_params.remote_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->codec_params.remote_sdp_ip); + switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip); switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); @@ -4737,8 +4894,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { switch_core_media_check_video_codecs(session); } - - if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && v_engine->codec_params.rm_encoding && v_engine->codec_params.remote_sdp_port) { + + if (switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && v_engine->cur_payload_map->rm_encoding && v_engine->cur_payload_map->remote_sdp_port) { /******************************************************************************************/ if (v_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) { //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE); @@ -4748,14 +4905,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi - if (remote_host && remote_port && !strcmp(remote_host, v_engine->codec_params.remote_sdp_ip) && remote_port == v_engine->codec_params.remote_sdp_port) { + if (remote_host && remote_port && !strcmp(remote_host, v_engine->cur_payload_map->remote_sdp_ip) && remote_port == v_engine->cur_payload_map->remote_sdp_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video params are unchanged for %s.\n", switch_channel_get_name(session->channel)); goto video_up; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video params changed for %s from %s:%d to %s:%d\n", switch_channel_get_name(session->channel), - remote_host, remote_port, v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port); + remote_host, remote_port, v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port); } } @@ -4763,17 +4920,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (switch_rtp_ready(v_engine->rtp_session)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "VIDEO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n", switch_channel_get_name(session->channel), - a_engine->codec_params.remote_sdp_ip, v_engine->codec_params.local_sdp_port, v_engine->codec_params.remote_sdp_ip, - v_engine->codec_params.remote_sdp_port, v_engine->codec_params.agreed_pt, + a_engine->cur_payload_map->remote_sdp_ip, v_engine->local_sdp_port, v_engine->cur_payload_map->remote_sdp_ip, + v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->agreed_pt, a_engine->read_impl.microseconds_per_packet / 1000); start_video_thread(session); - switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt); + switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt); } } - switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->codec_params.local_sdp_port); - switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, a_engine->codec_params.adv_sdp_ip); + switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->local_sdp_port); + switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE, a_engine->adv_sdp_ip); switch_channel_set_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp); @@ -4790,12 +4947,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } if (switch_rtp_set_remote_address - (v_engine->rtp_session, v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, + (v_engine->rtp_session, v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n", - v_engine->codec_params.remote_sdp_ip, v_engine->codec_params.remote_sdp_port); + v_engine->cur_payload_map->remote_sdp_ip, v_engine->cur_payload_map->remote_sdp_port); if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(session->channel, CF_WEBRTC) && !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val))) { /* Reactivate the NAT buster flag. */ @@ -4823,13 +4980,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "PROXY VIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n", switch_channel_get_name(session->channel), - a_engine->codec_params.remote_sdp_ip, - v_engine->codec_params.local_sdp_port, - v_engine->codec_params.remote_sdp_ip, - v_engine->codec_params.remote_sdp_port, v_engine->codec_params.agreed_pt, v_engine->read_impl.microseconds_per_packet / 1000); + a_engine->cur_payload_map->remote_sdp_ip, + v_engine->local_sdp_port, + v_engine->cur_payload_map->remote_sdp_ip, + v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->agreed_pt, v_engine->read_impl.microseconds_per_packet / 1000); if (switch_rtp_ready(v_engine->rtp_session)) { - switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->codec_params.agreed_pt); + switch_rtp_set_default_payload(v_engine->rtp_session, v_engine->cur_payload_map->agreed_pt); } } else { timer_name = smh->mparams->timer_name; @@ -4846,7 +5003,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } - if (!v_engine->codec_params.local_sdp_port) { + if (!v_engine->local_sdp_port) { switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1); } @@ -4869,31 +5026,32 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi flags[SWITCH_RTP_FLAG_NOBLOCK] = 0; flags[SWITCH_RTP_FLAG_VIDEO]++; - v_engine->rtp_session = switch_rtp_new(a_engine->codec_params.local_sdp_ip, - v_engine->codec_params.local_sdp_port, - v_engine->codec_params.remote_sdp_ip, - v_engine->codec_params.remote_sdp_port, - v_engine->codec_params.agreed_pt, + v_engine->rtp_session = switch_rtp_new(a_engine->local_sdp_ip, + v_engine->local_sdp_port, + v_engine->cur_payload_map->remote_sdp_ip, + v_engine->cur_payload_map->remote_sdp_port, + v_engine->cur_payload_map->agreed_pt, 1, 90000, flags, NULL, &err, switch_core_session_get_pool(session)); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%sVIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s]\n", switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ? "PROXY " : "", switch_channel_get_name(session->channel), - a_engine->codec_params.remote_sdp_ip, - v_engine->codec_params.local_sdp_port, - v_engine->codec_params.remote_sdp_ip, - v_engine->codec_params.remote_sdp_port, v_engine->codec_params.agreed_pt, + a_engine->cur_payload_map->remote_sdp_ip, + v_engine->local_sdp_port, + v_engine->cur_payload_map->remote_sdp_ip, + v_engine->cur_payload_map->remote_sdp_port, v_engine->cur_payload_map->agreed_pt, 0, switch_rtp_ready(v_engine->rtp_session) ? "SUCCESS" : err); - if (switch_rtp_ready(v_engine->rtp_session)) { - start_video_thread(session); - } - if (switch_rtp_ready(v_engine->rtp_session)) { const char *ssrc; + + switch_rtp_set_payload_map(v_engine->rtp_session, &v_engine->payload_map); + + start_video_thread(session); switch_channel_set_flag(session->channel, CF_VIDEO); + if ((ssrc = switch_channel_get_variable(session->channel, "rtp_use_video_ssrc"))) { uint32_t ssrc_ul = (uint32_t) strtoul(ssrc, NULL, 10); switch_rtp_set_ssrc(v_engine->rtp_session, ssrc_ul); @@ -5007,13 +5165,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_rtp_intentional_bugs(v_engine->rtp_session, v_engine->rtp_bugs | smh->mparams->manual_video_rtp_bugs); - if (v_engine->codec_params.recv_pt != v_engine->codec_params.agreed_pt) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "%s Set video receive payload to %u\n", switch_channel_get_name(session->channel), v_engine->codec_params.recv_pt); - switch_rtp_set_recv_pt(v_engine->rtp_session, v_engine->codec_params.recv_pt); - } + + //XX - switch_channel_set_variable_printf(session->channel, "rtp_use_video_pt", "%d", v_engine->codec_params.agreed_pt); + + switch_channel_set_variable_printf(session->channel, "rtp_use_video_pt", "%d", v_engine->cur_payload_map->agreed_pt); v_engine->ssrc = switch_rtp_get_ssrc(v_engine->rtp_session); switch_channel_set_variable_printf(session->channel, "rtp_use_video_ssrc", "%u", v_engine->ssrc); @@ -5082,7 +5238,8 @@ static const char *get_media_profile_name(switch_core_session_t *session, int se //? static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, switch_port_t port, const char *family, const char *ip, - int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int secure) + int cur_ptime, const char *append_audio, const char *sr, int use_cng, int cng_type, switch_event_t *map, int secure, + switch_sdp_type_t sdp_type) { int i = 0; int rate; @@ -5202,7 +5359,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, fmtp = check; } } - + if (smh->ianacodes[i] > 95 || switch_channel_test_flag(session->channel, CF_VERBOSE_SDP)) { int channels = get_channels(imp->iananame, imp->number_of_channels); @@ -5280,14 +5437,14 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port ); - if (!zstr(a_engine->codec_params.local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && - strcmp(a_engine->codec_params.local_sdp_ip, ice_out->cands[0][0].con_addr) - && a_engine->codec_params.local_sdp_port != ice_out->cands[0][0].con_port) { + if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && + strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr) + && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) { switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\n", tmp2, ice_out->cands[0][0].transport, c2, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port, - a_engine->codec_params.local_sdp_ip, a_engine->codec_params.local_sdp_port + a_engine->local_sdp_ip, a_engine->local_sdp_port ); } @@ -5299,14 +5456,14 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1) ); - if (!zstr(a_engine->codec_params.local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr) && - strcmp(a_engine->codec_params.local_sdp_ip, ice_out->cands[0][1].con_addr) - && a_engine->codec_params.local_sdp_port != ice_out->cands[0][1].con_port) { + if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr) && + strcmp(a_engine->local_sdp_ip, ice_out->cands[0][1].con_addr) + && a_engine->local_sdp_port != ice_out->cands[0][1].con_port) { switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\n", tmp2, ice_out->cands[0][0].transport, c2, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1), - a_engine->codec_params.local_sdp_ip, a_engine->codec_params.local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1) + a_engine->local_sdp_ip, a_engine->local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1) ); } } @@ -5458,7 +5615,7 @@ SWITCH_DECLARE(void)switch_core_media_set_local_sdp(switch_core_session_t *sessi //? #define SDPBUFLEN 65536 -SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *session, const char *ip, switch_port_t port, const char *sr, int force) +SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *session, switch_sdp_type_t sdp_type, const char *ip, switch_port_t port, const char *sr, int force) { char *buf; int ptime = 0; @@ -5486,6 +5643,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_media_handle_t *smh; ice_t *ice_out; int vp8 = 0; + payload_map_t *pmap; switch_assert(session); @@ -5528,7 +5686,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } } - fmtp_out = a_engine->codec_params.fmtp_out; + fmtp_out = a_engine->cur_payload_map->fmtp_out; username = smh->mparams->sdp_username; @@ -5543,26 +5701,40 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess smh->mparams->cng_pt = 0; } + if (!smh->payload_space) { int i; smh->payload_space = 98; - for (i = 0; i < smh->mparams->num_codecs; i++) { - const switch_codec_implementation_t *imp = smh->codecs[i]; + if (sdp_type == SDP_TYPE_REQUEST) { + for (i = 0; i < smh->mparams->num_codecs; i++) { + const switch_codec_implementation_t *imp = smh->codecs[i]; + + smh->ianacodes[i] = imp->ianacode; + + if (smh->ianacodes[i] > 64) { + if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95 && smh->mparams->te == smh->payload_space) { + smh->payload_space++; + } + if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && + smh->mparams->cng_pt && use_cng && smh->mparams->cng_pt == smh->payload_space) { + smh->payload_space++; + } + smh->ianacodes[i] = (switch_payload_t)smh->payload_space++; + } + - smh->ianacodes[i] = imp->ianacode; - - if (smh->ianacodes[i] > 64) { - if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95 && smh->mparams->te == smh->payload_space) { - smh->payload_space++; - } - if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && - smh->mparams->cng_pt && use_cng && smh->mparams->cng_pt == smh->payload_space) { - smh->payload_space++; - } - smh->ianacodes[i] = (switch_payload_t)smh->payload_space++; + switch_core_media_add_payload_map(session, + imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, + imp->iananame, + sdp_type, + smh->ianacodes[i], + imp->samples_per_second, + imp->microseconds_per_packet / 1000, + SWITCH_FALSE); } + } } @@ -5581,8 +5753,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } if (!ip) { - if (!(ip = a_engine->codec_params.adv_sdp_ip)) { - ip = a_engine->codec_params.proxy_sdp_ip; + if (!(ip = a_engine->adv_sdp_ip)) { + ip = a_engine->proxy_sdp_ip; } } @@ -5593,8 +5765,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } if (!port) { - if (!(port = a_engine->codec_params.adv_sdp_port)) { - port = a_engine->codec_params.proxy_sdp_port; + if (!(port = a_engine->adv_sdp_port)) { + port = a_engine->proxy_sdp_port; } } @@ -5604,7 +5776,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess return; } - if (!a_engine->codec_params.rm_encoding && (b_sdp = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) { + if (!a_engine->cur_payload_map->rm_encoding && (b_sdp = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) { switch_core_media_sdp_map(b_sdp, &map, &ptmap); } @@ -5655,7 +5827,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } - if (a_engine->codec_params.rm_encoding) { + if (a_engine->codec_negotiated) { /* switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=audio %d RTP/%sAVP%s", port, ((!zstr(local_audio_crypto_key) || switch_channel_test_flag(session->channel, CF_DTLS)) && @@ -5670,7 +5842,18 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess )); - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", a_engine->codec_params.pt); + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", a_engine->cur_payload_map->pt); + + + if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) { + switch_mutex_lock(smh->mutex); + for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { + if (pmap->pt != a_engine->cur_payload_map->pt) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt); + } + } + switch_mutex_unlock(smh->mutex); + } if ((smh->mparams->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF)) && smh->mparams->te > 95) { @@ -5684,24 +5867,37 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\n"); - rate = a_engine->codec_params.adv_rm_rate; + rate = a_engine->cur_payload_map->adv_rm_rate; - if (!a_engine->codec_params.adv_channels) { - a_engine->codec_params.adv_channels = get_channels(a_engine->codec_params.rm_encoding, 1); + if (!a_engine->cur_payload_map->adv_channels) { + a_engine->cur_payload_map->adv_channels = get_channels(a_engine->cur_payload_map->rm_encoding, 1); } - - if (a_engine->codec_params.adv_channels > 1) { + + if (a_engine->cur_payload_map->adv_channels > 1) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d/%d\n", - a_engine->codec_params.agreed_pt, a_engine->codec_params.rm_encoding, rate, a_engine->codec_params.adv_channels); + a_engine->cur_payload_map->agreed_pt, a_engine->cur_payload_map->rm_encoding, rate, a_engine->cur_payload_map->adv_channels); } else { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d\n", - a_engine->codec_params.agreed_pt, a_engine->codec_params.rm_encoding, rate); + a_engine->cur_payload_map->agreed_pt, a_engine->cur_payload_map->rm_encoding, rate); } if (fmtp_out) { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\n", a_engine->codec_params.agreed_pt, fmtp_out); + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\n", a_engine->cur_payload_map->agreed_pt, fmtp_out); } + if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) { + switch_mutex_lock(smh->mutex); + for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { + if (pmap->pt != a_engine->cur_payload_map->pt) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n", + pmap->pt, pmap->iananame, + pmap->rate); + } + } + switch_mutex_unlock(smh->mutex); + } + + if (a_engine->read_codec.implementation && !ptime) { ptime = a_engine->read_codec.implementation->microseconds_per_packet / 1000; } @@ -5722,7 +5918,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } else if (smh->mparams->cng_pt && use_cng) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d CN/8000\n", smh->mparams->cng_pt); - if (!a_engine->codec_params.rm_encoding) { + if (!a_engine->codec_negotiated) { smh->mparams->cng_pt = 0; } } @@ -5795,14 +5991,14 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port ); - if (!zstr(a_engine->codec_params.local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && - strcmp(a_engine->codec_params.local_sdp_ip, ice_out->cands[0][0].con_addr) - && a_engine->codec_params.local_sdp_port != ice_out->cands[0][0].con_port) { + if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && + strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr) + && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\n", tmp2, ice_out->cands[0][0].transport, c3, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port, - a_engine->codec_params.local_sdp_ip, a_engine->codec_params.local_sdp_port + a_engine->local_sdp_ip, a_engine->local_sdp_port ); } @@ -5817,14 +6013,14 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess - if (!zstr(a_engine->codec_params.local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && - strcmp(a_engine->codec_params.local_sdp_ip, ice_out->cands[0][0].con_addr) - && a_engine->codec_params.local_sdp_port != ice_out->cands[0][0].con_port) { + if (!zstr(a_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && + strcmp(a_engine->local_sdp_ip, ice_out->cands[0][0].con_addr) + && a_engine->local_sdp_port != ice_out->cands[0][0].con_port) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx raddr %s rport %d generation 0\n", tmp2, ice_out->cands[0][0].transport, c4, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (a_engine->rtcp_mux > 0 ? 0 : 1), - a_engine->codec_params.local_sdp_ip, a_engine->codec_params.local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1) + a_engine->local_sdp_ip, a_engine->local_sdp_port + (a_engine->rtcp_mux > 0 ? 0 : 1) ); } } @@ -5851,7 +6047,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (!switch_media_handle_test_media_flag(smh, SCMF_SUPPRESS_CNG) && smh->mparams->cng_pt && use_cng) { cng_type = smh->mparams->cng_pt; - if (!a_engine->codec_params.rm_encoding) { + if (!a_engine->codec_negotiated) { smh->mparams->cng_pt = 0; } } @@ -5865,7 +6061,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if ((!zstr(local_audio_crypto_key) && switch_channel_test_flag(session->channel, CF_SECURE)) || switch_channel_test_flag(session->channel, CF_DTLS)) { - generate_m(session, buf, SDPBUFLEN, port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 1); + generate_m(session, buf, SDPBUFLEN, port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 1, sdp_type); bp = (buf + strlen(buf)); /* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/ @@ -5876,7 +6072,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } if (both) { - generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 0); + generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, 0, append_audio, sr, use_cng, cng_type, map, 0, sdp_type); } } else { @@ -5902,7 +6098,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if ((!zstr(local_audio_crypto_key) && switch_channel_test_flag(session->channel, CF_SECURE)) || switch_channel_test_flag(session->channel, CF_DTLS)) { - generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 1); + generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 1, sdp_type); bp = (buf + strlen(buf)); /* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/ @@ -5916,7 +6112,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } if (both) { - generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 0); + generate_m(session, bp, SDPBUFLEN - strlen(buf), port, family, ip, cur_ptime, append_audio, sr, use_cng, cng_type, map, 0, sdp_type); } } @@ -5935,11 +6131,15 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } - if (!v_engine->codec_params.local_sdp_port) { + if (!v_engine->local_sdp_port) { switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 0); } - if ((v_port = v_engine->codec_params.adv_sdp_port)) { + if (switch_channel_test_flag(session->channel, CF_WEBRTC)) { + switch_media_handle_set_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO); + } + + if ((v_port = v_engine->adv_sdp_port)) { if (switch_channel_test_flag(smh->session->channel, CF_ICE)) { gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, ip, (switch_port_t)v_port); @@ -5959,14 +6159,27 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess /*****************************/ - if (v_engine->codec_params.rm_encoding) { + if (v_engine->codec_negotiated) { + payload_map_t *pmap; switch_core_media_set_video_codec(session, 0); - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", v_engine->codec_params.agreed_pt); + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", v_engine->cur_payload_map->agreed_pt); + + if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) { + switch_mutex_lock(smh->mutex); + for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { + if (pmap->pt != v_engine->cur_payload_map->pt) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt); + } + } + switch_mutex_unlock(smh->mutex); + } + } else if (smh->mparams->num_codecs) { int i; int already_did[128] = { 0 }; for (i = 0; i < smh->mparams->num_codecs; i++) { const switch_codec_implementation_t *imp = smh->codecs[i]; + if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { continue; @@ -5985,6 +6198,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", smh->ianacodes[i]); + if (!ptime) { ptime = imp->microseconds_per_packet / 1000; } @@ -5994,20 +6208,22 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\n"); - if (v_engine->codec_params.rm_encoding) { + if (v_engine->codec_negotiated) { const char *of; + payload_map_t *pmap; - if (!strcasecmp(v_engine->codec_params.rm_encoding, "VP8")) { - vp8 = v_engine->codec_params.pt; + if (!strcasecmp(v_engine->cur_payload_map->rm_encoding, "VP8")) { + vp8 = v_engine->cur_payload_map->pt; } - rate = v_engine->codec_params.rm_rate; + rate = v_engine->cur_payload_map->rm_rate; switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n", - v_engine->codec_params.pt, v_engine->codec_params.rm_encoding, - v_engine->codec_params.rm_rate); + v_engine->cur_payload_map->pt, v_engine->cur_payload_map->rm_encoding, + v_engine->cur_payload_map->rm_rate); + if (switch_channel_test_flag(session->channel, CF_RECOVERING)) { - pass_fmtp = v_engine->codec_params.rm_fmtp; + pass_fmtp = v_engine->cur_payload_map->rm_fmtp; } else { pass_fmtp = NULL; @@ -6026,9 +6242,23 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } if (pass_fmtp) { - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\n", v_engine->codec_params.pt, pass_fmtp); + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\n", v_engine->cur_payload_map->pt, pass_fmtp); } + + if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) { + switch_mutex_lock(smh->mutex); + for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { + if (pmap->pt != v_engine->cur_payload_map->pt) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n", + pmap->pt, pmap->iananame, pmap->rate); + + } + } + switch_mutex_unlock(smh->mutex); + } + + if (append_video) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s%s", append_video, end_of(append_video) == '\n' ? "" : "\n"); } @@ -6169,14 +6399,14 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port ); - if (!zstr(v_engine->codec_params.local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && - strcmp(v_engine->codec_params.local_sdp_ip, ice_out->cands[0][0].con_addr) - && v_engine->codec_params.local_sdp_port != ice_out->cands[0][0].con_port) { + if (!zstr(v_engine->local_sdp_ip) && !zstr(ice_out->cands[0][0].con_addr) && + strcmp(v_engine->local_sdp_ip, ice_out->cands[0][0].con_addr) + && v_engine->local_sdp_port != ice_out->cands[0][0].con_port) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx raddr %s rport %d generation 0\n", tmp2, ice_out->cands[0][0].transport, c3, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port, - v_engine->codec_params.local_sdp_ip, v_engine->codec_params.local_sdp_port + v_engine->local_sdp_ip, v_engine->local_sdp_port ); } @@ -6190,14 +6420,14 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess ); - if (!zstr(v_engine->codec_params.local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr) && - strcmp(v_engine->codec_params.local_sdp_ip, ice_out->cands[0][1].con_addr) - && v_engine->codec_params.local_sdp_port != ice_out->cands[0][1].con_port) { + if (!zstr(v_engine->local_sdp_ip) && !zstr(ice_out->cands[0][1].con_addr) && + strcmp(v_engine->local_sdp_ip, ice_out->cands[0][1].con_addr) + && v_engine->local_sdp_port != ice_out->cands[0][1].con_port) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n", tmp2, ice_out->cands[0][0].transport, c4, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port + (v_engine->rtcp_mux > 0 ? 0 : 1), - v_engine->codec_params.local_sdp_ip, v_engine->codec_params.local_sdp_port + (v_engine->rtcp_mux > 0 ? 0 : 1) + v_engine->local_sdp_ip, v_engine->local_sdp_port + (v_engine->rtcp_mux > 0 ? 0 : 1) ); } } @@ -6273,10 +6503,10 @@ SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session } if (connection) { - a_engine->codec_params.proxy_sdp_ip = switch_core_session_strdup(session, connection->c_address); + a_engine->proxy_sdp_ip = switch_core_session_strdup(session, connection->c_address); } - a_engine->codec_params.proxy_sdp_port = (switch_port_t) m->m_port; - if (a_engine->codec_params.proxy_sdp_ip && a_engine->codec_params.proxy_sdp_port) { + a_engine->proxy_sdp_port = (switch_port_t) m->m_port; + if (a_engine->proxy_sdp_ip && a_engine->proxy_sdp_port) { break; } } @@ -6332,8 +6562,8 @@ SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t if (!ip) { - if (!(ip = a_engine->codec_params.adv_sdp_ip)) { - ip = a_engine->codec_params.proxy_sdp_ip; + if (!(ip = a_engine->adv_sdp_ip)) { + ip = a_engine->proxy_sdp_ip; } } @@ -6343,8 +6573,8 @@ SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t } if (!port) { - if (!(port = a_engine->codec_params.adv_sdp_port)) { - port = a_engine->codec_params.proxy_sdp_port; + if (!(port = a_engine->adv_sdp_port)) { + port = a_engine->proxy_sdp_port; } } @@ -6471,20 +6701,20 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) return; } - if (zstr(a_engine->codec_params.local_sdp_ip) || !a_engine->codec_params.local_sdp_port) {// || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) { + if (zstr(a_engine->local_sdp_ip) || !a_engine->local_sdp_port) {// || switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) { if (switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_AUDIO, 1) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s I/O Error\n", switch_channel_get_name(session->channel)); return; } - a_engine->codec_params.iananame = switch_core_session_strdup(session, "PROXY"); - a_engine->codec_params.rm_rate = 8000; - a_engine->codec_params.adv_rm_rate = 8000; - a_engine->codec_params.codec_ms = 20; + a_engine->cur_payload_map->iananame = switch_core_session_strdup(session, "PROXY"); + a_engine->cur_payload_map->rm_rate = 8000; + a_engine->cur_payload_map->adv_rm_rate = 8000; + a_engine->cur_payload_map->codec_ms = 20; } new_sdp = switch_core_session_alloc(session, len); - switch_snprintf(port_buf, sizeof(port_buf), "%u", a_engine->codec_params.local_sdp_port); + switch_snprintf(port_buf, sizeof(port_buf), "%u", a_engine->local_sdp_port); p = smh->mparams->local_sdp_str; @@ -6504,15 +6734,15 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) goto end; } - if (a_engine->codec_params.local_sdp_ip && !strncmp("c=IN IP", p, 7)) { + if (a_engine->local_sdp_ip && !strncmp("c=IN IP", p, 7)) { strncpy(q, p, 7); p += 7; q += 7; - strncpy(q, strchr(a_engine->codec_params.adv_sdp_ip, ':') ? "6 " : "4 ", 2); + strncpy(q, strchr(a_engine->adv_sdp_ip, ':') ? "6 " : "4 ", 2); p +=2; q +=2; - strncpy(q, a_engine->codec_params.adv_sdp_ip, strlen(a_engine->codec_params.adv_sdp_ip)); - q += strlen(a_engine->codec_params.adv_sdp_ip); + strncpy(q, a_engine->adv_sdp_ip, strlen(a_engine->adv_sdp_ip)); + q += strlen(a_engine->adv_sdp_ip); while (p && *p && ((*p >= '0' && *p <= '9') || *p == '.' || *p == ':' || (*p >= 'A' && *p <= 'F') || (*p >= 'a' && *p <= 'f'))) { if (p >= pe) { @@ -6623,11 +6853,11 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session) } else if (!strncmp("m=video ", p, 8) && *(p + 8) != '0') { if (!has_video) { switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1); - v_engine->codec_params.rm_encoding = "PROXY-VID"; - v_engine->codec_params.rm_rate = 90000; - v_engine->codec_params.adv_rm_rate = 90000; - v_engine->codec_params.codec_ms = 0; - switch_snprintf(vport_buf, sizeof(vport_buf), "%u", v_engine->codec_params.adv_sdp_port); + v_engine->cur_payload_map->rm_encoding = "PROXY-VID"; + v_engine->cur_payload_map->rm_rate = 90000; + v_engine->cur_payload_map->adv_rm_rate = 90000; + v_engine->cur_payload_map->codec_ms = 0; + switch_snprintf(vport_buf, sizeof(vport_buf), "%u", v_engine->adv_sdp_port); if (switch_channel_media_ready(session->channel) && !switch_rtp_ready(v_engine->rtp_session)) { switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); switch_channel_set_flag(session->channel, CF_REINVITE); @@ -7055,9 +7285,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se const char *ip = NULL, *port = NULL; switch_channel_set_flag(session->channel, CF_PROXY_MODE); - if (a_engine->codec_params.rm_encoding) { - a_engine->codec_params.rm_encoding = NULL; - } + + a_engine->codec_negotiated = 0; + switch_core_media_set_local_sdp(session, NULL, SWITCH_FALSE); if (switch_true(switch_channel_get_variable(session->channel, "bypass_keep_codec"))) { @@ -7072,7 +7302,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se port = switch_channel_get_variable(other_channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE); switch_core_session_rwunlock(other_session); if (ip && port) { - switch_core_media_gen_local_sdp(session, ip, (switch_port_t)atoi(port), NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, ip, (switch_port_t)atoi(port), NULL, 1); } } @@ -7109,19 +7339,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_channel_set_variable(session->channel, "codec_string", msg->string_arg); } else { switch_channel_set_variable_printf(session->channel, "codec_string", "=%s%s%s,%s", - v_engine->codec_params.rm_encoding ? v_engine->codec_params.rm_encoding : "", - v_engine->codec_params.rm_encoding ? "," : "", - a_engine->codec_params.rm_encoding, msg->string_arg); + v_engine->cur_payload_map->rm_encoding ? v_engine->cur_payload_map->rm_encoding : "", + v_engine->cur_payload_map->rm_encoding ? "," : "", + a_engine->cur_payload_map->rm_encoding, msg->string_arg); } - - a_engine->codec_params.rm_encoding = NULL; - v_engine->codec_params.rm_encoding = NULL; + a_engine->codec_negotiated = 0; + v_engine->codec_negotiated = 0; switch_channel_clear_flag(session->channel, CF_VIDEO_POSSIBLE); switch_core_media_prepare_codecs(session, SWITCH_TRUE); switch_core_media_check_video_codecs(session); - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); } switch_media_handle_set_media_flag(smh, SCMF_RENEG_ON_REINVITE); @@ -7302,22 +7531,6 @@ SWITCH_DECLARE(void) switch_core_media_clear_rtp_flag(switch_core_session_t *ses } } -//? -SWITCH_DECLARE(void) switch_core_media_set_recv_pt(switch_core_session_t *session, switch_media_type_t type, switch_payload_t pt) -{ - switch_media_handle_t *smh; - - switch_assert(session); - - if (!(smh = session->media_handle)) { - return; - } - - if (switch_rtp_ready(smh->engines[type].rtp_session)) { - switch_rtp_set_recv_pt(smh->engines[type].rtp_session, pt); - } -} - //? SWITCH_DECLARE(void) switch_core_media_set_telephony_event(switch_core_session_t *session, switch_media_type_t type, switch_payload_t te) { @@ -7694,7 +7907,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_chosen(switch_core_sessi engine = &smh->engines[type]; - if (engine->codec_params.iananame) { + if (engine->cur_payload_map->iananame) { return SWITCH_STATUS_SUCCESS; } @@ -7726,18 +7939,18 @@ SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_ switch_channel_set_flag(session->channel, CF_PROXY_MEDIA); - a_engine->codec_params.iananame = switch_core_session_strdup(session, "PROXY"); - a_engine->codec_params.rm_rate = 8000; - a_engine->codec_params.adv_rm_rate = 8000; + a_engine->cur_payload_map->iananame = switch_core_session_strdup(session, "PROXY"); + a_engine->cur_payload_map->rm_rate = 8000; + a_engine->cur_payload_map->adv_rm_rate = 8000; - a_engine->codec_params.codec_ms = 20; + a_engine->cur_payload_map->codec_ms = 20; if (switch_stristr("m=video", r_sdp)) { switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_VIDEO, 1); - v_engine->codec_params.rm_encoding = "PROXY-VID"; - v_engine->codec_params.rm_rate = 90000; - v_engine->codec_params.adv_rm_rate = 90000; - v_engine->codec_params.codec_ms = 0; + v_engine->cur_payload_map->rm_encoding = "PROXY-VID"; + v_engine->cur_payload_map->rm_rate = 90000; + v_engine->cur_payload_map->adv_rm_rate = 90000; + v_engine->cur_payload_map->codec_ms = 0; switch_channel_set_flag(session->channel, CF_VIDEO); switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); } @@ -7806,10 +8019,10 @@ SWITCH_DECLARE(void) switch_core_media_proxy_codec(switch_core_session_t *sessio } for (map = m->m_rtpmaps; map; map = map->rm_next) { - a_engine->codec_params.iananame = switch_core_session_strdup(session, map->rm_encoding); - a_engine->codec_params.rm_rate = map->rm_rate; - a_engine->codec_params.adv_rm_rate = map->rm_rate; - a_engine->codec_params.codec_ms = ptime; + a_engine->cur_payload_map->iananame = switch_core_session_strdup(session, map->rm_encoding); + a_engine->cur_payload_map->rm_rate = map->rm_rate; + a_engine->cur_payload_map->adv_rm_rate = map->rm_rate; + a_engine->cur_payload_map->codec_ms = ptime; switch_core_media_set_codec(session, 0, smh->mparams->codec_flags); break; } @@ -7856,9 +8069,8 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; - - a_engine->codec_params.iananame = a_engine->codec_params.rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_name"); - a_engine->codec_params.rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_fmtp"); + a_engine->cur_payload_map->iananame = a_engine->cur_payload_map->rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_name"); + a_engine->cur_payload_map->rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_codec_fmtp"); if ((tmp = switch_channel_get_variable(session->channel, SWITCH_R_SDP_VARIABLE))) { smh->mparams->remote_sdp_str = switch_core_session_strdup(session, tmp); @@ -7885,52 +8097,52 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s } if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_rate"))) { - a_engine->codec_params.rm_rate = atoi(tmp); - a_engine->codec_params.adv_rm_rate = a_engine->codec_params.rm_rate; + a_engine->cur_payload_map->rm_rate = atoi(tmp); + a_engine->cur_payload_map->adv_rm_rate = a_engine->cur_payload_map->rm_rate; } if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_ptime"))) { - a_engine->codec_params.codec_ms = atoi(tmp); + a_engine->cur_payload_map->codec_ms = atoi(tmp); } if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_pt"))) { - a_engine->codec_params.pt = a_engine->codec_params.agreed_pt = (switch_payload_t)atoi(tmp); + a_engine->cur_payload_map->pt = a_engine->cur_payload_map->agreed_pt = (switch_payload_t)atoi(tmp); } if ((tmp = switch_channel_get_variable(session->channel, "rtp_audio_recv_pt"))) { - a_engine->codec_params.recv_pt = a_engine->codec_params.agreed_pt = (switch_payload_t)atoi(tmp);; + a_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp); } switch_core_media_set_codec(session, 1, smh->mparams->codec_flags); - a_engine->codec_params.adv_sdp_ip = smh->mparams->extrtpip = (char *) ip; - a_engine->codec_params.adv_sdp_port = a_engine->codec_params.local_sdp_port = (switch_port_t)atoi(port); + a_engine->adv_sdp_ip = smh->mparams->extrtpip = (char *) ip; + a_engine->adv_sdp_port = a_engine->local_sdp_port = (switch_port_t)atoi(port); if (!zstr(ip)) { - a_engine->codec_params.local_sdp_ip = switch_core_session_strdup(session, ip); - smh->mparams->rtpip = a_engine->codec_params.local_sdp_ip; + a_engine->local_sdp_ip = switch_core_session_strdup(session, ip); + smh->mparams->rtpip = a_engine->local_sdp_ip; } if (!zstr(a_ip)) { - a_engine->codec_params.adv_sdp_ip = switch_core_session_strdup(session, a_ip); + a_engine->adv_sdp_ip = switch_core_session_strdup(session, a_ip); } if (r_ip && r_port) { - a_engine->codec_params.remote_sdp_ip = (char *) r_ip; - a_engine->codec_params.remote_sdp_port = (switch_port_t)atoi(r_port); + a_engine->cur_payload_map->remote_sdp_ip = (char *) r_ip; + a_engine->cur_payload_map->remote_sdp_port = (switch_port_t)atoi(r_port); } if (switch_channel_test_flag(session->channel, CF_VIDEO)) { if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_pt"))) { - v_engine->codec_params.pt = v_engine->codec_params.agreed_pt = (switch_payload_t)atoi(tmp); + v_engine->cur_payload_map->pt = v_engine->cur_payload_map->agreed_pt = (switch_payload_t)atoi(tmp); } if ((tmp = switch_channel_get_variable(session->channel, "rtp_video_recv_pt"))) { - v_engine->codec_params.recv_pt = a_engine->codec_params.agreed_pt = (switch_payload_t)atoi(tmp);; + v_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp);; } - v_engine->codec_params.rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_name"); - v_engine->codec_params.rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_fmtp"); + v_engine->cur_payload_map->rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_name"); + v_engine->cur_payload_map->rm_fmtp = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_fmtp"); ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_VIDEO_IP_VARIABLE); port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE); @@ -7940,23 +8152,24 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s switch_channel_set_flag(session->channel, CF_VIDEO_POSSIBLE); if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_codec_rate"))) { - v_engine->codec_params.rm_rate = atoi(tmp); - v_engine->codec_params.adv_rm_rate = v_engine->codec_params.rm_rate; + v_engine->cur_payload_map->rm_rate = atoi(tmp); + v_engine->cur_payload_map->adv_rm_rate = v_engine->cur_payload_map->rm_rate; } if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_video_codec_ptime"))) { - v_engine->codec_params.codec_ms = atoi(tmp); + v_engine->cur_payload_map->codec_ms = atoi(tmp); } - v_engine->codec_params.adv_sdp_port = v_engine->codec_params.local_sdp_port = (switch_port_t)atoi(port); + v_engine->adv_sdp_port = v_engine->local_sdp_port = (switch_port_t)atoi(port); if (r_ip && r_port) { - v_engine->codec_params.remote_sdp_ip = (char *) r_ip; - v_engine->codec_params.remote_sdp_port = (switch_port_t)atoi(r_port); + v_engine->cur_payload_map->remote_sdp_ip = (char *) r_ip; + v_engine->cur_payload_map->remote_sdp_port = (switch_port_t)atoi(r_port); } } - switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 1); + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); + switch_core_media_set_video_codec(session, 1); if (switch_core_media_activate_rtp(session) != SWITCH_STATUS_SUCCESS) { return; @@ -7983,15 +8196,10 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_AUDIO)) { - switch_core_media_set_recv_pt(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->codec_params.recv_pt); switch_rtp_set_telephony_event(a_engine->rtp_session, smh->mparams->te); switch_rtp_set_telephony_recv_event(a_engine->rtp_session, smh->mparams->recv_te); } - if (switch_core_media_ready(session, SWITCH_MEDIA_TYPE_VIDEO)) { - switch_core_media_set_recv_pt(session, SWITCH_MEDIA_TYPE_VIDEO, v_engine->codec_params.recv_pt); - } - } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4d644adf0c..a0e80013f0 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -325,7 +325,6 @@ struct switch_rtp { int8_t sending_dtmf; uint8_t need_mark; switch_payload_t payload; - switch_payload_t rpayload; switch_rtp_invalid_handler_t invalid_handler; void *private_data; uint32_t ts; @@ -398,6 +397,10 @@ struct switch_rtp { switch_size_t last_flush_packet_count; uint32_t interdigit_delay; switch_core_session_t *session; + payload_map_t **pmaps; + payload_map_t *pmap_tail; + int pmap_ttl; + #ifdef ENABLE_ZRTP zrtp_session_t *zrtp_session; zrtp_profile_t *zrtp_profile; @@ -1859,6 +1862,19 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_request_port(const char *ip) return port; } +SWITCH_DECLARE(switch_status_t) switch_rtp_set_payload_map(switch_rtp_t *rtp_session, payload_map_t **pmap) +{ + + if (rtp_session) { + switch_mutex_lock(rtp_session->flag_mutex); + rtp_session->pmaps = pmap; + switch_mutex_unlock(rtp_session->flag_mutex); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs) { rtp_session->rtp_bugs = bugs; @@ -2973,7 +2989,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->recv_msg.header.cc = 0; rtp_session->payload = payload; - rtp_session->rpayload = payload; switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval); rtp_session->conf_samples_per_interval = samples_per_interval; @@ -3164,11 +3179,6 @@ SWITCH_DECLARE(void) switch_rtp_set_telephony_recv_event(switch_rtp_t *rtp_sessi } } -SWITCH_DECLARE(void) switch_rtp_set_recv_pt(switch_rtp_t *rtp_session, switch_payload_t pt) -{ - rtp_session->rpayload = pt; -} - SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt) { @@ -4063,6 +4073,27 @@ static int jb_valid(switch_rtp_t *rtp_session) return 1; } +static int check_recv_payload(switch_rtp_t *rtp_session) +{ + int ok = 0; + + if (rtp_session->pmaps && *rtp_session->pmaps) { + payload_map_t *pmap; + switch_mutex_lock(rtp_session->flag_mutex); + for (pmap = *rtp_session->pmaps; pmap && pmap->allocated; pmap = pmap->next) { + if (!pmap->negotiated) { + continue; + } + if (rtp_session->recv_msg.header.pt == pmap->pt) { + ok = 1; + } + } + switch_mutex_unlock(rtp_session->flag_mutex); + } + + return ok; +} + #define return_cng_frame() do_cng = 1; goto timer_check static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes, switch_frame_flag_t *flags, switch_bool_t return_jb_packet) @@ -4149,7 +4180,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (status == SWITCH_STATUS_SUCCESS && *bytes) { if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { *flags &= ~SFF_RTCP; - if (rtp_session->recv_msg.header.pt != rtp_session->rpayload && + if (!check_recv_payload(rtp_session) && (!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && rtp_session->rtcp_recv_msg_p->header.version == 2 && @@ -4319,7 +4350,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t #ifdef ENABLE_SRTP if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && rtp_session->recv_msg.header.version == 2 && - ((rtp_session->recv_msg.header.pt == rtp_session->rpayload) || + (check_recv_payload(rtp_session) || (rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) || (rtp_session->cng_pt && rtp_session->recv_msg.header.pt == rtp_session->cng_pt))) { //if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && (!rtp_session->ice.ice_user || rtp_session->recv_msg.header.version == 2)) { @@ -4376,7 +4407,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->last_read_ts = ts; } - if (rtp_session->flags[SWITCH_RTP_FLAG_BYTESWAP] && rtp_session->recv_msg.header.pt == rtp_session->rpayload) { + if (rtp_session->flags[SWITCH_RTP_FLAG_BYTESWAP] && check_recv_payload(rtp_session)) { switch_swap_linear((int16_t *)RTP_BODY(rtp_session), (int) *bytes - rtp_header_len); } @@ -4602,7 +4633,8 @@ static int using_ice(switch_rtp_t *rtp_session) return 0; } -static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_type, switch_frame_flag_t *flags, switch_io_flag_t io_flags) +static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_type, + payload_map_t **pmapP, switch_frame_flag_t *flags, switch_io_flag_t io_flags) { switch_channel_t *channel = NULL; @@ -4969,11 +5001,33 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && !rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] && rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && - (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && - rtp_session->recv_msg.header.pt != rtp_session->rpayload && - !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PAYLOAD) && !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PACKETS)) { - /* drop frames of incorrect payload number and return CNG frame instead */ - return_cng_frame(); + (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt)) { + int accept_packet = 0; + + + if (rtp_session->pmaps && *rtp_session->pmaps) { + payload_map_t *pmap; + switch_mutex_lock(rtp_session->flag_mutex); + for (pmap = *rtp_session->pmaps; pmap && pmap->allocated; pmap = pmap->next) { + if (!pmap->negotiated) { + continue; + } + + if (rtp_session->recv_msg.header.pt == pmap->pt) { + accept_packet = 1; + if (pmapP) { + *pmapP = pmap; + } + } + } + switch_mutex_unlock(rtp_session->flag_mutex); + } + + if (!accept_packet && + !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PAYLOAD) && !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PACKETS)) { + /* drop frames of incorrect payload number and return CNG frame instead */ + return_cng_frame(); + } } if (!bytes && (io_flags & SWITCH_IO_FLAG_NOBLOCK)) { @@ -5085,7 +5139,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) { #if 0 - if (rtp_session->recv_msg.header.version == 2 && rtp_session->recv_msg.header.pt == rtp_session->rpayload) { + if (rtp_session->recv_msg.header.version == 2 && check_recv_payload(rtp_session)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Ignoring udptl packet of size of %ld bytes that looks strikingly like a RTP packet.\n", (long)bytes); bytes = 0; @@ -5335,7 +5389,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void return SWITCH_STATUS_FALSE; } - bytes = rtp_common_read(rtp_session, payload_type, flags, io_flags); + bytes = rtp_common_read(rtp_session, payload_type, NULL, flags, io_flags); if (bytes < 0) { *datalen = 0; @@ -5415,7 +5469,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp return SWITCH_STATUS_FALSE; } - bytes = rtp_common_read(rtp_session, &frame->payload, &frame->flags, io_flags); + bytes = rtp_common_read(rtp_session, &frame->payload, &frame->pmap, &frame->flags, io_flags); frame->data = RTP_BODY(rtp_session); frame->packet = &rtp_session->recv_msg; @@ -5504,7 +5558,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi return SWITCH_STATUS_FALSE; } - bytes = rtp_common_read(rtp_session, payload_type, flags, io_flags); + bytes = rtp_common_read(rtp_session, payload_type, NULL, flags, io_flags); *data = RTP_BODY(rtp_session); if (bytes < 0) { @@ -6146,12 +6200,26 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra rtp_session->stats.outbound.packet_count++; } + if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps && rtp_session->pmap_ttl > 1) { + payload_map_t *pmap; + switch_mutex_lock(rtp_session->flag_mutex); + + for (pmap = *rtp_session->pmaps; pmap; pmap = pmap->next) { + if (pmap->hash == frame->pmap->hash && !strcmp(pmap->iananame, frame->pmap->iananame)) { + payload = pmap->recv_pt; + break; + } + } + switch_mutex_unlock(rtp_session->flag_mutex); + } + if (fwd) { send_msg = frame->packet; len = frame->packetlen; ts = 0; // Trying this based on http://jira.freeswitch.org/browse/MODSOFIA-90 //if (frame->codec && frame->codec->agreed_pt == frame->payload) { + send_msg->header.pt = payload; //} } else { diff --git a/src/switch_utils.c b/src/switch_utils.c index 0eb66f6a1b..12b417b40a 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -114,7 +114,7 @@ SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_fr memcpy(new_frame->data, orig->data, orig->datalen); new_frame->codec = NULL; - + new_frame->pmap = NULL; *clone = new_frame; return SWITCH_STATUS_SUCCESS; From 37d692244810aa402264495f0abf2d489fae8e30 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Nov 2013 03:48:32 +0500 Subject: [PATCH 037/656] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 27f3645ff7..a574f4010a 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.5.6b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.5.6], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [5]) -AC_SUBST(SWITCH_VERSION_MICRO, [6b]) +AC_SUBST(SWITCH_VERSION_MICRO, [6]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 80dc61594b8a3f4da2ca19865f4c74beb55756f7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Nov 2013 03:49:31 +0500 Subject: [PATCH 038/656] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index a574f4010a..42256e2dda 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.5.6], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.5.7b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [5]) -AC_SUBST(SWITCH_VERSION_MICRO, [6]) +AC_SUBST(SWITCH_VERSION_MICRO, [7b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From f0335d0f517064419dc36cc3ea1e343830d3e326 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Nov 2013 03:53:12 +0500 Subject: [PATCH 039/656] FS-5948 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 0a98cbf983..527de9b8fb 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1492,8 +1492,8 @@ static void our_sofia_event_callback(nua_event_t event, sofia_reg_check_socket(profile, sofia_private->call_id, sofia_private->network_ip, sofia_private->network_port); + nua_handle_destroy(nh); } - nua_handle_destroy(nh); } break; case nua_r_authenticate: From f97ca68f8e47299954b3854f0606552b9a0d7144 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 7 Nov 2013 20:31:58 -0500 Subject: [PATCH 040/656] mod_rayo: add component --- src/mod/event_handlers/mod_rayo/Makefile | 4 +- .../conf/autoload_configs/rayo.conf.xml | 8 +- src/mod/event_handlers/mod_rayo/mod_rayo.c | 14 +- .../event_handlers/mod_rayo/rayo_components.c | 4 +- .../event_handlers/mod_rayo/rayo_components.h | 4 +- .../event_handlers/mod_rayo/rayo_elements.c | 32 ++- .../event_handlers/mod_rayo/rayo_elements.h | 5 +- ...efax_component.c => rayo_fax_components.c} | 243 +++++++++++++++--- 8 files changed, 257 insertions(+), 57 deletions(-) rename src/mod/event_handlers/mod_rayo/{rayo_receivefax_component.c => rayo_fax_components.c} (60%) diff --git a/src/mod/event_handlers/mod_rayo/Makefile b/src/mod/event_handlers/mod_rayo/Makefile index bfb38dbd6c..a3bfc45d47 100644 --- a/src/mod/event_handlers/mod_rayo/Makefile +++ b/src/mod/event_handlers/mod_rayo/Makefile @@ -11,10 +11,10 @@ LOCAL_OBJS= $(IKS_LA) \ nlsml.o \ rayo_components.o \ rayo_elements.o \ + rayo_fax_components.o \ rayo_input_component.o \ rayo_output_component.o \ rayo_prompt_component.o \ - rayo_receivefax_component.o \ rayo_record_component.o \ sasl.o \ srgs.o \ @@ -24,11 +24,11 @@ LOCAL_SOURCES= \ nlsml.c \ rayo_components.c \ rayo_elements.c \ + rayo_fax_components.c \ rayo_input_component.c \ rayo_output_component.c \ rayo_prompt_component.c \ rayo_record_component.c \ - rayo_receivefax_component.c \ sasl.c \ srgs.c \ xmpp_streams.c diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index c8171569af..3fdc772daf 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -16,11 +16,11 @@ - - + + - - + + diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 51d1614751..f852d2c5f8 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -952,6 +952,7 @@ static void rayo_call_cleanup(struct rayo_actor *actor) iks_delete(revent); switch_event_destroy(&event); + switch_core_hash_destroy(&call->pcps); } /** @@ -1130,13 +1131,23 @@ static struct rayo_call *_rayo_call_create(const char *uuid, const char *file, i return rayo_call_init(call, pool, uuid, file, line); } +/** + * Mixer destructor + */ +static void rayo_mixer_cleanup(struct rayo_actor *actor) +{ + struct rayo_mixer *mixer = RAYO_MIXER(actor); + switch_core_hash_destroy(&mixer->members); + switch_core_hash_destroy(&mixer->subscribers); +} + /** * Initialize mixer */ static struct rayo_mixer *rayo_mixer_init(struct rayo_mixer *mixer, switch_memory_pool_t *pool, const char *name, const char *file, int line) { char *mixer_jid = switch_mprintf("%s@%s", name, RAYO_JID(globals.server)); - rayo_actor_init(RAYO_ACTOR(mixer), pool, RAT_MIXER, "", name, mixer_jid, NULL, rayo_mixer_send, file, line); + rayo_actor_init(RAYO_ACTOR(mixer), pool, RAT_MIXER, "", name, mixer_jid, rayo_mixer_cleanup, rayo_mixer_send, file, line); switch_core_hash_init(&mixer->members, pool); switch_core_hash_init(&mixer->subscribers, pool); switch_safe_free(mixer_jid); @@ -1307,6 +1318,7 @@ static void rayo_peer_server_cleanup(struct rayo_actor *actor) RAYO_UNLOCK(client); RAYO_DESTROY(client); } + switch_core_hash_destroy(&rserver->clients); switch_mutex_unlock(globals.clients_mutex); } diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.c b/src/mod/event_handlers/mod_rayo/rayo_components.c index 2448e166a8..7ad96d2a7d 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_components.c @@ -227,7 +227,7 @@ switch_status_t rayo_components_load(switch_loadable_module_interface_t **module rayo_output_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || rayo_prompt_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || rayo_record_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS || - rayo_receivefax_component_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { + rayo_fax_components_load(module_interface, pool, config_file) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_TERM; } return SWITCH_STATUS_SUCCESS; @@ -242,7 +242,7 @@ switch_status_t rayo_components_shutdown(void) rayo_output_component_shutdown(); rayo_prompt_component_shutdown(); rayo_record_component_shutdown(); - rayo_receivefax_component_shutdown(); + rayo_fax_components_shutdown(); return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_rayo/rayo_components.h b/src/mod/event_handlers/mod_rayo/rayo_components.h index 8d3909dd4d..5d1367d645 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_components.h +++ b/src/mod/event_handlers/mod_rayo/rayo_components.h @@ -61,14 +61,14 @@ extern switch_status_t rayo_input_component_load(switch_loadable_module_interfac extern switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); -extern switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern switch_status_t rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern switch_status_t rayo_components_shutdown(void); extern switch_status_t rayo_input_component_shutdown(void); extern switch_status_t rayo_output_component_shutdown(void); extern switch_status_t rayo_prompt_component_shutdown(void); extern switch_status_t rayo_record_component_shutdown(void); -extern switch_status_t rayo_receivefax_component_shutdown(void); +extern switch_status_t rayo_fax_components_shutdown(void); extern void rayo_component_send_start(struct rayo_component *component, iks *iq); extern void rayo_component_send_iq_error(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type); diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.c b/src/mod/event_handlers/mod_rayo/rayo_elements.c index a6e4f09140..78209c3bd6 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.c +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.c @@ -49,6 +49,17 @@ ELEMENT(RAYO_INPUT) ATTRIB(start-timers, true, bool) ELEMENT_END +/** + * command validation + */ +ELEMENT(RAYO_JOIN) + ATTRIB(xmlns,, any) + STRING_ATTRIB(direction, duplex, "send,recv,duplex") + STRING_ATTRIB(media, bridge, "bridge,direct") + ATTRIB(call-uri,, any) + ATTRIB(mixer-name,, any) +ELEMENT_END + /** * component validation */ @@ -80,6 +91,13 @@ ELEMENT(RAYO_PROMPT) ATTRIB(barge-in, true, bool) ELEMENT_END +/** + * command validation + */ +ELEMENT(RAYO_RECEIVEFAX) + ATTRIB(xmlns,, any) +ELEMENT_END + /** * component validation */ @@ -97,22 +115,12 @@ ELEMENT(RAYO_RECORD) ELEMENT_END /** - * command validation + * command validation */ -ELEMENT(RAYO_JOIN) +ELEMENT(RAYO_SENDFAX) ATTRIB(xmlns,, any) - STRING_ATTRIB(direction, duplex, "send,recv,duplex") - STRING_ATTRIB(media, bridge, "bridge,direct") - ATTRIB(call-uri,, any) - ATTRIB(mixer-name,, any) ELEMENT_END -/** - * command validation - */ -ELEMENT(RAYO_RECEIVEFAX) - ATTRIB(xmlns,, any) -ELEMENT_END /* For Emacs: * Local Variables: diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.h b/src/mod/event_handlers/mod_rayo/rayo_elements.h index 4c061dc35e..e76809cc9e 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.h +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.h @@ -32,12 +32,13 @@ #include "iks_helpers.h" ELEMENT_DECL(RAYO_INPUT) +ELEMENT_DECL(RAYO_JOIN) ELEMENT_DECL(RAYO_OUTPUT) ELEMENT_DECL(RAYO_OUTPUT_SEEK) ELEMENT_DECL(RAYO_PROMPT) -ELEMENT_DECL(RAYO_RECORD) -ELEMENT_DECL(RAYO_JOIN) ELEMENT_DECL(RAYO_RECEIVEFAX) +ELEMENT_DECL(RAYO_RECORD) +ELEMENT_DECL(RAYO_SENDFAX) #endif diff --git a/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c similarity index 60% rename from src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c rename to src/mod/event_handlers/mod_rayo/rayo_fax_components.c index 75528f8b52..9cd48e2c2c 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_receivefax_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c @@ -23,7 +23,7 @@ * Contributor(s): * Chris Rienzo * - * rayo_receivefax_component.c -- Rayo receivefax component implementation + * rayo_fax_components.c -- Rayo receivefax and sendfax components implementation * */ #include "rayo_components.h" @@ -36,23 +36,197 @@ static struct { const char *file_prefix; } globals; -struct receivefax_component { +struct fax_component { /** component base class */ struct rayo_component base; + /** Flag to stop fax */ + int stop; +}; + +#define FAX_COMPONENT(x) ((struct fax_component *)x) + +struct receivefax_component { + /** fax component base class */ + struct fax_component base; /** true if HTTP PUT needs to be done after fax is received */ int http_put_after_receive; /** fax stored on local filesystem */ const char *local_filename; /** fax final target (may be same as local filename) */ const char *filename; - /** Flag to stop fax */ - int stop; }; -#define RECEIVEFAX_FINISH "finish", RAYO_FAX_COMPLETE_NS - #define RECEIVEFAX_COMPONENT(x) ((struct receivefax_component *)x) +#define FAX_FINISH "finish", RAYO_FAX_COMPLETE_NS + +/** + * Start execution of call sendfax component + * @param call the call to send fax to + * @param msg the original request + * @param session_data the call's session + */ +static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message *msg, void *session_data) +{ + iks *iq = msg->payload; + switch_core_session_t *session = (switch_core_session_t *)session_data; + struct fax_component *sendfax_component = NULL; + iks *sendfax = iks_find(iq, "sendfax"); + iks *response = NULL; + switch_event_t *execute_event = NULL; + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_memory_pool_t *pool; + iks *document; + const char *fax_document; + const char *fax_header; + const char *fax_identity; + const char *pages; + + /* validate attributes */ + if (!VALIDATE_RAYO_SENDFAX(sendfax)) { + return iks_new_error(iq, STANZA_ERROR_BAD_REQUEST); + } + + /* fax is only allowed if the call is not currently joined */ + if (rayo_call_is_joined(RAYO_CALL(call))) { + return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't send fax on a joined call"); + } + + if (!rayo_call_set_faxing(RAYO_CALL(call), 1)) { + return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress"); + } + + /* get fax document */ + document = iks_find(sendfax, "document"); + if (!document) { + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "missing document"); + } + fax_document = iks_find_attrib_soft(document, "url"); + if (zstr(fax_document)) { + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "missing document url"); + } + + /* is valid URL type? */ + if (!strncasecmp(fax_document, "http://", 7) || strncasecmp(fax_document, "https://", 8)) { + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + /* need to fetch document from server... */ + switch_api_execute("http_get", fax_document, session, &stream); + if (!zstr(stream.data) && !strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, sizeof(SWITCH_PATH_SEPARATOR) - 1)) { + fax_document = switch_core_session_strdup(session, stream.data); + } else { + switch_safe_free(stream.data); + return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to fetch document"); + } + switch_safe_free(stream.data); + } else if (!strncasecmp(fax_document, "file://", 7)) { + fax_document = fax_document + 7; + if (zstr(fax_document)) { + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid file:// url"); + } + } else if (strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, sizeof(SWITCH_PATH_SEPARATOR) - 1)) { + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "unsupported url type"); + } + + /* does document exist? */ + if (!switch_file_exists(fax_document, pool)) { + return iks_new_error_detailed_printf(iq, STANZA_ERROR_BAD_REQUEST, "file not found: %s", fax_document); + } + + /* get fax identity and header */ + fax_identity = iks_find_attrib_soft(document, "identity"); + if (!zstr(fax_identity)) { + switch_channel_set_variable(channel, "fax_ident", fax_identity); + } else { + switch_channel_set_variable(channel, "fax_ident", NULL); + } + fax_header = iks_find_attrib_soft(document, "header"); + if (!zstr(fax_header)) { + switch_channel_set_variable(channel, "fax_header", fax_header); + } else { + switch_channel_set_variable(channel, "fax_header", NULL); + } + + /* get pages to send */ + pages = iks_find_attrib_soft(document, "pages"); + if (!zstr(pages)) { + if (switch_regex_match(pages, "[1-9][0-9]*(-[1-9][0-9]*)?") == SWITCH_STATUS_FALSE) { + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid pages value"); + } else { + int start = 0; + int end = 0; + char *pages_dup = switch_core_session_strdup(session, pages); + char *sep = strchr(pages_dup, '-'); + if (sep) { + *sep = '\0'; + sep++; + end = atoi(sep); + } + start = atoi(pages_dup); + if (end && end < start) { + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid pages value"); + } + switch_channel_set_variable(channel, "fax_start_page", pages_dup); + switch_channel_set_variable(channel, "fax_end_page", sep); + } + } else { + switch_channel_set_variable(channel, "fax_start_page", NULL); + switch_channel_set_variable(channel, "fax_end_page", NULL); + } + + /* create sendfax component */ + switch_core_new_memory_pool(&pool); + sendfax_component = switch_core_alloc(pool, sizeof(*sendfax_component)); + rayo_component_init((struct rayo_component *)sendfax_component, pool, RAT_CALL_COMPONENT, "sendfax", NULL, call, iks_find_attrib(iq, "from")); + + /* add channel variable so that fax component can be located from fax events */ + switch_channel_set_variable(channel, "rayo_fax_jid", RAYO_JID(sendfax_component)); + + /* clear fax result variables */ + switch_channel_set_variable(channel, "fax_success", NULL); + switch_channel_set_variable(channel, "fax_result_code", NULL); + switch_channel_set_variable(channel, "fax_result_text", NULL); + switch_channel_set_variable(channel, "fax_document_transferred_pages", NULL); + switch_channel_set_variable(channel, "fax_document_total_pages", NULL); + switch_channel_set_variable(channel, "fax_image_resolution", NULL); + switch_channel_set_variable(channel, "fax_image_size", NULL); + switch_channel_set_variable(channel, "fax_bad_rows", NULL); + switch_channel_set_variable(channel, "fax_transfer_rate", NULL); + switch_channel_set_variable(channel, "fax_ecm_used", NULL); + switch_channel_set_variable(channel, "fax_local_station_id", NULL); + switch_channel_set_variable(channel, "fax_remote_station_id", NULL); + + /* clear fax interrupt variable */ + switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); + + /* execute txfax APP */ + if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "txfax"); + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", fax_document); + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); + if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { + switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); + } + + if (switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS) { + response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to txfax (queue event failed)"); + if (execute_event) { + switch_event_destroy(&execute_event); + } + RAYO_UNLOCK(sendfax_component); + } else { + /* component starting... */ + rayo_component_send_start(RAYO_COMPONENT(sendfax_component), iq); + } + } else { + response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create txfax event"); + RAYO_UNLOCK(sendfax_component); + } + + return response; +} + /** * Start execution of call receivefax component * @param call the call to receive fax from @@ -153,9 +327,9 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess } /** - * Stop execution of receivefax component + * Stop execution of fax component */ -static iks *stop_receivefax_component(struct rayo_actor *component, struct rayo_message *msg, void *data) +static iks *stop_fax_component(struct rayo_actor *component, struct rayo_message *msg, void *data) { iks *iq = msg->payload; switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id); @@ -164,7 +338,7 @@ static iks *stop_receivefax_component(struct rayo_actor *component, struct rayo_ switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", RAYO_JID(component)); switch_core_session_rwunlock(session); } - RECEIVEFAX_COMPONENT(component)->stop = 1; + FAX_COMPONENT(component)->stop = 1; return iks_new_iq_result(iq); } @@ -190,18 +364,19 @@ static void insert_fax_metadata(switch_event_t *event, const char *name, iks *re } /** - * Handle rxfax completion event from FreeSWITCH core + * Handle fax completion event from FreeSWITCH core * @param event received from FreeSWITCH core. It will be destroyed by the core after this function returns. */ static void on_execute_complete_event(switch_event_t *event) { const char *application = switch_event_get_header(event, "Application"); - if (!zstr(application) && !strcmp(application, "rxfax")) { + + if (!zstr(application) && (!strcmp(application, "rxfax") || !strcmp(application, "txfax"))) { + int is_rxfax = !strcmp(application, "rxfax"); const char *uuid = switch_event_get_header(event, "Unique-ID"); const char *fax_jid = switch_event_get_header(event, "variable_rayo_fax_jid"); struct rayo_actor *component; if (!zstr(fax_jid) && (component = RAYO_LOCATE(fax_jid))) { - const char *url = RECEIVEFAX_COMPONENT(component)->filename; iks *result; iks *complete; iks *fax; @@ -216,11 +391,8 @@ static void on_execute_complete_event(switch_event_t *event) switch_core_session_rwunlock(session); } - /* flag faxing as done */ - rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0); - - /* transfer HTTP document and delete local copy */ - if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component))) { + /* RX only: transfer HTTP document and delete local copy */ + if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component))) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename); @@ -237,16 +409,16 @@ static void on_execute_complete_event(switch_event_t *event) /* successful fax? */ if (have_fax_document && switch_true(switch_event_get_header(event, "variable_fax_success"))) { - result = rayo_component_create_complete_event(RAYO_COMPONENT(component), RECEIVEFAX_FINISH); - } else if (have_fax_document && RECEIVEFAX_COMPONENT(component)->stop) { + result = rayo_component_create_complete_event(RAYO_COMPONENT(component), FAX_FINISH); + } else if (have_fax_document && FAX_COMPONENT(component)->stop) { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); } else { result = rayo_component_create_complete_event(RAYO_COMPONENT(component), COMPONENT_COMPLETE_ERROR); } complete = iks_find(result, "complete"); - /* add fax document information */ - if (have_fax_document) { + /* RX only: add fax document information */ + if (is_rxfax && have_fax_document) { const char *pages = switch_event_get_header(event, "variable_fax_document_transferred_pages"); if (!zstr(pages) && switch_is_number(pages) && atoi(pages) > 0) { const char *resolution = switch_event_get_header(event, "variable_fax_file_image_resolution"); @@ -256,10 +428,10 @@ static void on_execute_complete_event(switch_event_t *event) iks_insert_attrib(fax, "xmlns", RAYO_FAX_COMPLETE_NS); if (RECEIVEFAX_COMPONENT(component)->http_put_after_receive) { - iks_insert_attrib(fax, "url", url); + iks_insert_attrib(fax, "url", RECEIVEFAX_COMPONENT(component)->filename); } else { /* convert absolute path to file:// URI */ - iks_insert_attrib_printf(fax, "url", "file://%s", url); + iks_insert_attrib_printf(fax, "url", "file://%s", RECEIVEFAX_COMPONENT(component)->filename); } if (!zstr(resolution)) { @@ -286,6 +458,9 @@ static void on_execute_complete_event(switch_event_t *event) insert_fax_metadata(event, "fax_local_station_id", complete); insert_fax_metadata(event, "fax_remote_station_id", complete); + /* flag faxing as done */ + rayo_call_set_faxing(RAYO_CALL(RAYO_COMPONENT(component)->parent), 0); + rayo_component_send_complete_event(RAYO_COMPONENT(component), result); RAYO_UNLOCK(component); @@ -313,14 +488,14 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ /* get params */ { - switch_xml_t settings = switch_xml_child(cfg, "receivefax"); + switch_xml_t settings = switch_xml_child(cfg, "fax"); if (settings) { switch_xml_t param; for (param = switch_xml_child(settings, "param"); param; param = param->next) { const char *var = switch_xml_attr_soft(param, "name"); const char *val = switch_xml_attr_soft(param, "value"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "param: %s = %s\n", var, val); - if (!strcasecmp(var, "file-prefix")) { + if (!strcasecmp(var, "receivefax-file-prefix")) { if (!zstr(val)) { globals.file_prefix = switch_core_strdup(pool, val); } @@ -331,7 +506,7 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax file-prefix = %s\n", globals.file_prefix); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "receivefax-file-prefix = %s\n", globals.file_prefix); switch_xml_free(xml); @@ -339,31 +514,34 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ } /** - * Initialize receivefax component + * Initialize fax components * @param module_interface * @param pool memory pool to allocate from * @param config_file to use * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_receivefax_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) +switch_status_t rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) { if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_TERM; } - switch_event_bind("rayo_receivefax_component", SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, on_execute_complete_event, NULL); + switch_event_bind("rayo_fax_components", SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE, NULL, on_execute_complete_event, NULL); rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":receivefax", start_receivefax_component); - rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "receivefax", "set:"RAYO_EXT_NS":stop", stop_receivefax_component); + rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "receivefax", "set:"RAYO_EXT_NS":stop", stop_fax_component); + + rayo_actor_command_handler_add(RAT_CALL, "", "set:"RAYO_FAX_NS":sendfax", start_sendfax_component); + rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "sendfax", "set:"RAYO_EXT_NS":stop", stop_fax_component); return SWITCH_STATUS_SUCCESS; } /** - * Shutdown receivefax component + * Shutdown fax components * @return SWITCH_STATUS_SUCCESS if successful */ -switch_status_t rayo_receivefax_component_shutdown(void) +switch_status_t rayo_fax_components_shutdown(void) { switch_event_unbind_callback(on_execute_complete_event); @@ -380,3 +558,4 @@ switch_status_t rayo_receivefax_component_shutdown(void) * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet */ + From 96ceb6363ebe42b56fcdfa837d3226440cc8656a Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 7 Nov 2013 21:41:31 -0500 Subject: [PATCH 041/656] mod_rayo: bugfixes --- src/mod/event_handlers/mod_rayo/rayo_fax_components.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c index 9cd48e2c2c..420853104a 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c @@ -107,12 +107,12 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message } /* is valid URL type? */ - if (!strncasecmp(fax_document, "http://", 7) || strncasecmp(fax_document, "https://", 8)) { + if (!strncasecmp(fax_document, "http://", 7) || !strncasecmp(fax_document, "https://", 8)) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); /* need to fetch document from server... */ switch_api_execute("http_get", fax_document, session, &stream); - if (!zstr(stream.data) && !strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, sizeof(SWITCH_PATH_SEPARATOR) - 1)) { + if (!zstr(stream.data) && !strncmp(fax_document, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) { fax_document = switch_core_session_strdup(session, stream.data); } else { switch_safe_free(stream.data); @@ -124,12 +124,12 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message if (zstr(fax_document)) { return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "invalid file:// url"); } - } else if (strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, sizeof(SWITCH_PATH_SEPARATOR) - 1)) { + } else if (strncasecmp(fax_document, SWITCH_PATH_SEPARATOR, strlen(SWITCH_PATH_SEPARATOR))) { return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "unsupported url type"); } /* does document exist? */ - if (!switch_file_exists(fax_document, pool)) { + if (switch_file_exists(fax_document, pool) != SWITCH_STATUS_SUCCESS) { return iks_new_error_detailed_printf(iq, STANZA_ERROR_BAD_REQUEST, "file not found: %s", fax_document); } @@ -392,7 +392,7 @@ static void on_execute_complete_event(switch_event_t *event) } /* RX only: transfer HTTP document and delete local copy */ - if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component))) { + if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename); From bf03df9f146152b68c46dc1ad289337bed9afc07 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 7 Nov 2013 23:01:40 -0600 Subject: [PATCH 042/656] fix windows compiler warnings and vs2010 reswig --- .../mod_managed/freeswitch_wrap.2010.cxx | 1515 ++++++++++++++++- .../mod_managed/managed/swig.2010.cs | 1350 ++++++++++++++- src/switch_core_media.c | 4 +- 3 files changed, 2807 insertions(+), 62 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 9afb1d2758..6b36513455 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -1930,6 +1930,16 @@ SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_MAX_TRANS_get() { } +SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_CORE_SESSION_MAX_PRIVATES_get() { + int jresult ; + int result; + + result = (int)(2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_dtmf_t_digit_set(void * jarg1, char jarg2) { switch_dtmf_t *arg1 = (switch_dtmf_t *) 0 ; char arg2 ; @@ -6320,6 +6330,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_thread_data_t_alloc_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_thread_data_t_pool_set(void * jarg1, void * jarg2) { + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + switch_memory_pool_t *arg2 = (switch_memory_pool_t *) 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + arg2 = (switch_memory_pool_t *)jarg2; + if (arg1) (arg1)->pool = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_thread_data_t_pool_get(void * jarg1) { + void * jresult ; + switch_thread_data_t *arg1 = (switch_thread_data_t *) 0 ; + switch_memory_pool_t *result = 0 ; + + arg1 = (switch_thread_data_t *)jarg1; + result = (switch_memory_pool_t *) ((arg1)->pool); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_thread_data_t() { void * jresult ; switch_thread_data_t *result = 0 ; @@ -6604,6 +6636,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_node_t_hup_profile_get(void * } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_node_t_direction_set(void * jarg1, int jarg2) { + switch_device_node_t *arg1 = (switch_device_node_t *) 0 ; + switch_call_direction_t arg2 ; + + arg1 = (switch_device_node_t *)jarg1; + arg2 = (switch_call_direction_t)jarg2; + if (arg1) (arg1)->direction = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_device_node_t_direction_get(void * jarg1) { + int jresult ; + switch_device_node_t *arg1 = (switch_device_node_t *) 0 ; + switch_call_direction_t result; + + arg1 = (switch_device_node_t *)jarg1; + result = (switch_call_direction_t) ((arg1)->direction); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_node_t_parent_set(void * jarg1, void * jarg2) { switch_device_node_t *arg1 = (switch_device_node_t *) 0 ; switch_device_record_s *arg2 = (switch_device_record_s *) 0 ; @@ -6688,6 +6742,50 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_total_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_total_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->total_in = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_total_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->total_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_total_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->total_out = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_total_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->total_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_offhook_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -6710,6 +6808,50 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_offhook_get(vo } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_offhook_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->offhook_in = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_offhook_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->offhook_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_offhook_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->offhook_out = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_offhook_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->offhook_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_active_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -6732,6 +6874,50 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_active_get(voi } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_active_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->active_in = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_active_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->active_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_active_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->active_out = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_active_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->active_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_held_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -6754,6 +6940,50 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_held_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_held_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->held_in = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_held_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->held_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_held_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->held_out = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_held_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->held_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_hup_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -6776,6 +7006,50 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_hup_get(void * } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_hup_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->hup_in = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_hup_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->hup_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_hup_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->hup_out = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_hup_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->hup_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ringing_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -6798,6 +7072,50 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ringing_get(vo } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ringing_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->ringing_in = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ringing_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->ringing_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ringing_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->ringing_out = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ringing_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->ringing_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_early_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -6820,6 +7138,72 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_early_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_early_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->early_in = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_early_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->early_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_early_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->early_out = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_early_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->early_out); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ring_wait_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->ring_wait = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ring_wait_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->ring_wait); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_device_stats_t() { void * jresult ; switch_device_stats_t *result = 0 ; @@ -6942,6 +7326,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_stats_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_last_stats_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_device_stats_t *arg2 = (switch_device_stats_t *) 0 ; + + arg1 = (switch_device_record_t *)jarg1; + arg2 = (switch_device_stats_t *)jarg2; + if (arg1) (arg1)->last_stats = *arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_last_stats_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_device_stats_t *result = 0 ; + + arg1 = (switch_device_record_t *)jarg1; + result = (switch_device_stats_t *)& ((arg1)->last_stats); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_state_set(void * jarg1, int jarg2) { switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; switch_device_state_t arg2 ; @@ -7070,6 +7476,146 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_last_call_time_get(v } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_ring_start_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->ring_start = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_ring_start_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->ring_start); + jresult = new switch_time_t((const switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_ring_stop_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->ring_stop = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_ring_stop_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->ring_stop); + jresult = new switch_time_t((const switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_hold_start_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->hold_start = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_hold_start_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->hold_start); + jresult = new switch_time_t((const switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_hold_stop_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->hold_stop = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_hold_stop_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->hold_stop); + jresult = new switch_time_t((const switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_call_start_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->call_start = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_call_start_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->call_start); + jresult = new switch_time_t((const switch_time_t &)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_uuid_list_set(void * jarg1, void * jarg2) { switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; device_uuid_node_s *arg2 = (device_uuid_node_s *) 0 ; @@ -7158,6 +7704,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_pool_get(void * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_user_data_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_device_record_t *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->user_data = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_user_data_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + void *result = 0 ; + + arg1 = (switch_device_record_t *)jarg1; + result = (void *) ((arg1)->user_data); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_device_record_t() { void * jresult ; switch_device_record_t *result = 0 ; @@ -9436,6 +10004,18 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_switchname() { } +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_domain(int jarg1) { + char * jresult ; + switch_bool_t arg1 ; + char *result = 0 ; + + arg1 = (switch_bool_t)jarg1; + result = (char *)switch_core_get_domain(arg1); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_set_variable(char * jarg1, char * jarg2) { char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; @@ -9722,6 +10302,14 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_exec(void * jarg1, void * } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_video_reset(void * jarg1) { + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + + arg1 = (switch_core_session_t *)jarg1; + switch_core_session_video_reset(arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_execute_application_get_flags(void * jarg1, char * jarg2, char * jarg3, void * jarg4) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -9802,27 +10390,31 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_receive_event(void * jarg1 } -SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_private(void * jarg1) { +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_private_class(void * jarg1, int jarg2) { void * jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_pvt_class_t arg2 ; void *result = 0 ; arg1 = (switch_core_session_t *)jarg1; - result = (void *)switch_core_session_get_private(arg1); + arg2 = (switch_pvt_class_t)jarg2; + result = (void *)switch_core_session_get_private_class(arg1,arg2); jresult = (void *)result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_set_private(void * jarg1, void * jarg2) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_set_private_class(void * jarg1, void * jarg2, int jarg3) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; void *arg2 = (void *) 0 ; + switch_pvt_class_t arg3 ; switch_status_t result; arg1 = (switch_core_session_t *)jarg1; arg2 = (void *)jarg2; - result = (switch_status_t)switch_core_session_set_private(arg1,arg2); + arg3 = (switch_pvt_class_t)jarg3; + result = (switch_status_t)switch_core_session_set_private_class(arg1,arg2,arg3); jresult = result; return jresult; } @@ -11071,14 +11663,14 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_db_test_reactive(void * jarg1, ch } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_perform_file_open(char * jarg1, char * jarg2, int jarg3, void * jarg4, char * jarg5, unsigned char jarg6, unsigned long jarg7, unsigned int jarg8, void * jarg9) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_perform_file_open(char * jarg1, char * jarg2, int jarg3, void * jarg4, char * jarg5, unsigned long jarg6, unsigned long jarg7, unsigned int jarg8, void * jarg9) { int jresult ; char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; int arg3 ; switch_file_handle_t *arg4 = (switch_file_handle_t *) 0 ; char *arg5 = (char *) 0 ; - uint8_t arg6 ; + uint32_t arg6 ; uint32_t arg7 ; unsigned int arg8 ; switch_memory_pool_t *arg9 = (switch_memory_pool_t *) 0 ; @@ -11089,7 +11681,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_perform_file_open(char * jarg1, ch arg3 = (int)jarg3; arg4 = (switch_file_handle_t *)jarg4; arg5 = (char *)jarg5; - arg6 = (uint8_t)jarg6; + arg6 = (uint32_t)jarg6; arg7 = (uint32_t)jarg7; arg8 = (unsigned int)jarg8; arg9 = (switch_memory_pool_t *)jarg9; @@ -13605,6 +14197,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_stream_system_fork(char * jarg1, void * } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ice_direction(void * jarg1) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_call_direction_t result; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_call_direction_t)switch_ice_direction(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_set(void * jarg1, char * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; char *arg2 = (char *) 0 ; @@ -13788,6 +14392,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_api_interf } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_json_api_interface_set(void * jarg1, void * jarg2) { + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_json_api_interface_t *arg2 = (switch_json_api_interface_t *) 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + arg2 = (switch_json_api_interface_t *)jarg2; + if (arg1) (arg1)->json_api_interface = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_interface_json_api_interface_get(void * jarg1) { + void * jresult ; + switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; + switch_json_api_interface_t *result = 0 ; + + arg1 = (switch_loadable_module_interface *)jarg1; + result = (switch_json_api_interface_t *) ((arg1)->json_api_interface); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_file_interface_set(void * jarg1, void * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; switch_file_interface_t *arg2 = (switch_file_interface_t *) 0 ; @@ -14233,6 +14859,18 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_api_interface(ch } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_json_api_interface(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_json_api_interface_t *result = 0 ; + + arg1 = (char *)jarg1; + result = (switch_json_api_interface_t *)switch_loadable_module_get_json_api_interface((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_file_interface(char * jarg1) { void * jresult ; char *arg1 = (char *) 0 ; @@ -14379,6 +15017,22 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_api_execute(char * jarg1, char * jarg2, } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_json_api_execute(void * jarg1, void * jarg2, void * jarg3) { + int jresult ; + cJSON *arg1 = (cJSON *) 0 ; + switch_core_session_t *arg2 = (switch_core_session_t *) 0 ; + cJSON **arg3 = (cJSON **) 0 ; + switch_status_t result; + + arg1 = (cJSON *)jarg1; + arg2 = (switch_core_session_t *)jarg2; + arg3 = (cJSON **)jarg3; + result = (switch_status_t)switch_json_api_execute(arg1,arg2,arg3); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_load_module(char * jarg1, char * jarg2, int jarg3, void * jarg4) { int jresult ; char *arg1 = (char *) 0 ; @@ -14507,6 +15161,40 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_ready(void * jarg1) { } +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_get_secondary_recover_callback(char * jarg1) { + void * jresult ; + char *arg1 = (char *) 0 ; + switch_core_recover_callback_t result; + + arg1 = (char *)jarg1; + result = (switch_core_recover_callback_t)switch_core_get_secondary_recover_callback((char const *)arg1); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_register_secondary_recover_callback(char * jarg1, void * jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_core_recover_callback_t arg2 = (switch_core_recover_callback_t) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_core_recover_callback_t)jarg2; + result = (switch_status_t)switch_core_register_secondary_recover_callback((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_unregister_secondary_recover_callback(char * jarg1) { + char *arg1 = (char *) 0 ; + + arg1 = (char *)jarg1; + switch_core_unregister_secondary_recover_callback((char const *)arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_CMD_CHUNK_LEN_get() { int jresult ; int result; @@ -14624,6 +15312,16 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_console_run_complete_func(char * jarg1, } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_console_push_match_unique(void * jarg1, char * jarg2) { + switch_console_callback_match_t **arg1 = (switch_console_callback_match_t **) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_console_callback_match_t **)jarg1; + arg2 = (char *)jarg2; + switch_console_push_match_unique(arg1,(char const *)arg2); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_console_push_match(void * jarg1, char * jarg2) { switch_console_callback_match_t **arg1 = (switch_console_callback_match_t **) 0 ; char *arg2 = (char *) 0 ; @@ -15405,6 +16103,26 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_find_local_ip(char * jarg1, int jarg2, } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_find_interface_ip(char * jarg1, int jarg2, void * jarg3, char * jarg4, int jarg5) { + int jresult ; + char *arg1 = (char *) 0 ; + int arg2 ; + int *arg3 = (int *) 0 ; + char *arg4 = (char *) 0 ; + int arg5 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (int)jarg2; + arg3 = (int *)jarg3; + arg4 = (char *)jarg4; + arg5 = (int)jarg5; + result = (switch_status_t)switch_find_interface_ip(arg1,arg2,arg3,(char const *)arg4,arg5); + jresult = result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_get_addr(char * jarg1, void * jarg2, void * jarg3, void * jarg4) { char * jresult ; char *arg1 = (char *) 0 ; @@ -17483,6 +18201,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_caller_profile_direction_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_logical_direction_set(void * jarg1, int jarg2) { + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_call_direction_t arg2 ; + + arg1 = (switch_caller_profile *)jarg1; + arg2 = (switch_call_direction_t)jarg2; + if (arg1) (arg1)->logical_direction = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_caller_profile_logical_direction_get(void * jarg1) { + int jresult ; + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_call_direction_t result; + + arg1 = (switch_caller_profile *)jarg1; + result = (switch_call_direction_t) ((arg1)->logical_direction); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_soft_set(void * jarg1, void * jarg2) { switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; profile_node_t *arg2 = (profile_node_t *) 0 ; @@ -18459,6 +19199,28 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_frame_user_data_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_frame_pmap_set(void * jarg1, void * jarg2) { + switch_frame *arg1 = (switch_frame *) 0 ; + payload_map_t *arg2 = (payload_map_t *) 0 ; + + arg1 = (switch_frame *)jarg1; + arg2 = (payload_map_t *)jarg2; + if (arg1) (arg1)->pmap = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_frame_pmap_get(void * jarg1) { + void * jresult ; + switch_frame *arg1 = (switch_frame *) 0 ; + payload_map_t *result = 0 ; + + arg1 = (switch_frame *)jarg1; + result = (payload_map_t *) ((arg1)->pmap); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_frame() { void * jresult ; switch_frame *result = 0 ; @@ -20827,24 +21589,24 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_file_handle_native_rate_get(v } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_file_handle_channels_set(void * jarg1, unsigned char jarg2) { +SWIGEXPORT void SWIGSTDCALL CSharp_switch_file_handle_channels_set(void * jarg1, unsigned long jarg2) { switch_file_handle *arg1 = (switch_file_handle *) 0 ; - uint8_t arg2 ; + uint32_t arg2 ; arg1 = (switch_file_handle *)jarg1; - arg2 = (uint8_t)jarg2; + arg2 = (uint32_t)jarg2; if (arg1) (arg1)->channels = arg2; } -SWIGEXPORT unsigned char SWIGSTDCALL CSharp_switch_file_handle_channels_get(void * jarg1) { - unsigned char jresult ; +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_file_handle_channels_get(void * jarg1) { + unsigned long jresult ; switch_file_handle *arg1 = (switch_file_handle *) 0 ; - uint8_t result; + uint32_t result; arg1 = (switch_file_handle *)jarg1; - result = (uint8_t) ((arg1)->channels); - jresult = result; + result = (uint32_t) ((arg1)->channels); + jresult = (unsigned long)result; return jresult; } @@ -21672,6 +22434,50 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_file_handle__params_get(void * jarg1 } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_file_handle_cur_channels_set(void * jarg1, unsigned long jarg2) { + switch_file_handle *arg1 = (switch_file_handle *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_file_handle *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->cur_channels = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_file_handle_cur_channels_get(void * jarg1) { + unsigned long jresult ; + switch_file_handle *arg1 = (switch_file_handle *) 0 ; + uint32_t result; + + arg1 = (switch_file_handle *)jarg1; + result = (uint32_t) ((arg1)->cur_channels); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_file_handle_cur_samplerate_set(void * jarg1, unsigned long jarg2) { + switch_file_handle *arg1 = (switch_file_handle *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_file_handle *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->cur_samplerate = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_file_handle_cur_samplerate_get(void * jarg1) { + unsigned long jresult ; + switch_file_handle *arg1 = (switch_file_handle *) 0 ; + uint32_t result; + + arg1 = (switch_file_handle *)jarg1; + result = (uint32_t) ((arg1)->cur_samplerate); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_file_handle() { void * jresult ; switch_file_handle *result = 0 ; @@ -26566,6 +27372,243 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_api_interface(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_interface_name_set(void * jarg1, char * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->interface_name = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->interface_name, (const char *)arg2); + } else { + arg1->interface_name = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_json_api_interface_interface_name_get(void * jarg1) { + char * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + char *result = 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + result = (char *) ((arg1)->interface_name); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_desc_set(void * jarg1, char * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->desc = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->desc, (const char *)arg2); + } else { + arg1->desc = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_json_api_interface_desc_get(void * jarg1) { + char * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + char *result = 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + result = (char *) ((arg1)->desc); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_function_set(void * jarg1, void * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_json_api_function_t arg2 = (switch_json_api_function_t) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (switch_json_api_function_t)jarg2; + if (arg1) (arg1)->function = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_json_api_interface_function_get(void * jarg1) { + void * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_json_api_function_t result; + + arg1 = (switch_json_api_interface *)jarg1; + result = (switch_json_api_function_t) ((arg1)->function); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_syntax_set(void * jarg1, char * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + char *arg2 = (char *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) { + arg1->syntax = (char const *) (new char[strlen((const char *)arg2)+1]); + strcpy((char *)arg1->syntax, (const char *)arg2); + } else { + arg1->syntax = 0; + } + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_json_api_interface_syntax_get(void * jarg1) { + char * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + char *result = 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + result = (char *) ((arg1)->syntax); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_rwlock_set(void * jarg1, void * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_thread_rwlock_t *arg2 = (switch_thread_rwlock_t *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (switch_thread_rwlock_t *)jarg2; + if (arg1) (arg1)->rwlock = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_json_api_interface_rwlock_get(void * jarg1) { + void * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_thread_rwlock_t *result = 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + result = (switch_thread_rwlock_t *) ((arg1)->rwlock); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_refs_set(void * jarg1, int jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + int arg2 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (int)jarg2; + if (arg1) (arg1)->refs = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_json_api_interface_refs_get(void * jarg1) { + int jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + int result; + + arg1 = (switch_json_api_interface *)jarg1; + result = (int) ((arg1)->refs); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_reflock_set(void * jarg1, void * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_mutex_t *arg2 = (switch_mutex_t *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (switch_mutex_t *)jarg2; + if (arg1) (arg1)->reflock = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_json_api_interface_reflock_get(void * jarg1) { + void * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_mutex_t *result = 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + result = (switch_mutex_t *) ((arg1)->reflock); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_parent_set(void * jarg1, void * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_loadable_module_interface_t *arg2 = (switch_loadable_module_interface_t *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (switch_loadable_module_interface_t *)jarg2; + if (arg1) (arg1)->parent = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_json_api_interface_parent_get(void * jarg1) { + void * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_loadable_module_interface_t *result = 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + result = (switch_loadable_module_interface_t *) ((arg1)->parent); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_api_interface_next_set(void * jarg1, void * jarg2) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_json_api_interface *arg2 = (switch_json_api_interface *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + arg2 = (switch_json_api_interface *)jarg2; + if (arg1) (arg1)->next = arg2; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_json_api_interface_next_get(void * jarg1) { + void * jresult ; + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + switch_json_api_interface *result = 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + result = (switch_json_api_interface *) ((arg1)->next); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_json_api_interface() { + void * jresult ; + switch_json_api_interface *result = 0 ; + + result = (switch_json_api_interface *)new switch_json_api_interface(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_json_api_interface(void * jarg1) { + switch_json_api_interface *arg1 = (switch_json_api_interface *) 0 ; + + arg1 = (switch_json_api_interface *)jarg1; + delete arg1; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_session_set(void * jarg1, void * jarg2) { switch_slin_data *arg1 = (switch_slin_data *) 0 ; switch_core_session_t *arg2 = (switch_core_session_t *) 0 ; @@ -28570,6 +29613,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_direction(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_logical_direction(void * jarg1) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_call_direction_t result; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_call_direction_t)switch_channel_logical_direction(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_direction(void * jarg1, int jarg2) { + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_call_direction_t arg2 ; + + arg1 = (switch_channel_t *)jarg1; + arg2 = (switch_call_direction_t)jarg2; + switch_channel_set_direction(arg1,arg2); +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_switch_channel_get_session(void * jarg1) { void * jresult ; switch_channel_t *arg1 = (switch_channel_t *) 0 ; @@ -30383,6 +31448,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_serialize_json(void * jarg1, void } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_serialize_json_obj(void * jarg1, void * jarg2) { + int jresult ; + switch_event_t *arg1 = (switch_event_t *) 0 ; + cJSON **arg2 = (cJSON **) 0 ; + switch_status_t result; + + arg1 = (switch_event_t *)jarg1; + arg2 = (cJSON **)jarg2; + result = (switch_status_t)switch_event_serialize_json_obj(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_create_json(void * jarg1, char * jarg2) { int jresult ; switch_event_t **arg1 = (switch_event_t **) 0 ; @@ -30587,6 +31666,18 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_event_add_presence_data_cols(void * ja } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_json_add_presence_data_cols(void * jarg1, void * jarg2, char * jarg3) { + switch_event_t *arg1 = (switch_event_t *) 0 ; + cJSON *arg2 = (cJSON *) 0 ; + char *arg3 = (char *) 0 ; + + arg1 = (switch_event_t *)jarg1; + arg2 = (cJSON *)jarg2; + arg3 = (char *)jarg3; + switch_json_add_presence_data_cols(arg1,arg2,(char const *)arg3); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_event_launch_dispatch_threads(unsigned long jarg1) { uint32_t arg1 ; @@ -30595,6 +31686,334 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_event_launch_dispatch_threads(unsigned } +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_event_channel_broadcast(char * jarg1, void * jarg2, char * jarg3, unsigned long jarg4) { + unsigned long jresult ; + char *arg1 = (char *) 0 ; + cJSON **arg2 = (cJSON **) 0 ; + char *arg3 = (char *) 0 ; + switch_event_channel_id_t arg4 ; + uint32_t result; + + arg1 = (char *)jarg1; + arg2 = (cJSON **)jarg2; + arg3 = (char *)jarg3; + arg4 = (switch_event_channel_id_t)jarg4; + result = (uint32_t)switch_event_channel_broadcast((char const *)arg1,arg2,(char const *)arg3,arg4); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_event_channel_unbind(char * jarg1, void * jarg2) { + unsigned long jresult ; + char *arg1 = (char *) 0 ; + switch_event_channel_func_t arg2 = (switch_event_channel_func_t) 0 ; + uint32_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_event_channel_func_t)jarg2; + result = (uint32_t)switch_event_channel_unbind((char const *)arg1,arg2); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_channel_bind(char * jarg1, void * jarg2, void * jarg3) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_event_channel_func_t arg2 = (switch_event_channel_func_t) 0 ; + switch_event_channel_id_t *arg3 = (switch_event_channel_id_t *) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_event_channel_func_t)jarg2; + arg3 = (switch_event_channel_id_t *)jarg3; + result = (switch_status_t)switch_event_channel_bind((char const *)arg1,arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_NO_EVENT_CHANNEL_ID_get() { + int jresult ; + int result; + + result = (int)(0); + jresult = result; + return jresult; +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_EVENT_CHANNEL_GLOBAL_get() { + char * jresult ; + char *result = 0 ; + + result = (char *)("__global__"); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_clear(void * jarg1) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + switch_status_t result; + + arg1 = (switch_live_array_t *)jarg1; + result = (switch_status_t)switch_live_array_clear(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_bootstrap(void * jarg1, char * jarg2, unsigned long jarg3) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_event_channel_id_t arg3 ; + switch_status_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_event_channel_id_t)jarg3; + result = (switch_status_t)switch_live_array_bootstrap(arg1,(char const *)arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_destroy(void * jarg1) { + int jresult ; + switch_live_array_t **arg1 = (switch_live_array_t **) 0 ; + switch_status_t result; + + arg1 = (switch_live_array_t **)jarg1; + result = (switch_status_t)switch_live_array_destroy(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_create(char * jarg1, char * jarg2, unsigned long jarg3, void * jarg4) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_event_channel_id_t arg3 ; + switch_live_array_t **arg4 = (switch_live_array_t **) 0 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_event_channel_id_t)jarg3; + arg4 = (switch_live_array_t **)jarg4; + result = (switch_status_t)switch_live_array_create((char const *)arg1,(char const *)arg2,arg3,arg4); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_live_array_get(void * jarg1, char * jarg2) { + void * jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + cJSON *result = 0 ; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + result = (cJSON *)switch_live_array_get(arg1,(char const *)arg2); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_live_array_get_idx(void * jarg1, int jarg2) { + void * jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + int arg2 ; + cJSON *result = 0 ; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (int)jarg2; + result = (cJSON *)switch_live_array_get_idx(arg1,arg2); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_del(void * jarg1, char * jarg2) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + switch_status_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + result = (switch_status_t)switch_live_array_del(arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_add(void * jarg1, char * jarg2, int jarg3, void * jarg4, int jarg5) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + int arg3 ; + cJSON **arg4 = (cJSON **) 0 ; + switch_bool_t arg5 ; + switch_status_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (int)jarg3; + arg4 = (cJSON **)jarg4; + arg5 = (switch_bool_t)jarg5; + result = (switch_status_t)switch_live_array_add(arg1,(char const *)arg2,arg3,arg4,arg5); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_visible(void * jarg1, int jarg2, int jarg3) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + switch_bool_t arg2 ; + switch_bool_t arg3 ; + switch_status_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (switch_bool_t)jarg2; + arg3 = (switch_bool_t)jarg3; + result = (switch_status_t)switch_live_array_visible(arg1,arg2,arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_isnew(void * jarg1) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + switch_bool_t result; + + arg1 = (switch_live_array_t *)jarg1; + result = (switch_bool_t)switch_live_array_isnew(arg1); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_live_array_lock(void * jarg1) { + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + + arg1 = (switch_live_array_t *)jarg1; + switch_live_array_lock(arg1); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_live_array_unlock(void * jarg1) { + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + + arg1 = (switch_live_array_t *)jarg1; + switch_live_array_unlock(arg1); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_live_array_set_user_data(void * jarg1, void * jarg2) { + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (void *)jarg2; + switch_live_array_set_user_data(arg1,arg2); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_live_array_set_command_handler(void * jarg1, void * jarg2) { + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + switch_live_array_command_handler_t arg2 = (switch_live_array_command_handler_t) 0 ; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (switch_live_array_command_handler_t)jarg2; + switch_live_array_set_command_handler(arg1,arg2); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_live_array_parse_json(void * jarg1, unsigned long jarg2) { + cJSON *arg1 = (cJSON *) 0 ; + switch_event_channel_id_t arg2 ; + + arg1 = (cJSON *)jarg1; + arg2 = (switch_event_channel_id_t)jarg2; + switch_live_array_parse_json(arg1,arg2); +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_add_alias(void * jarg1, char * jarg2, char * jarg3) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + switch_bool_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + result = (switch_bool_t)switch_live_array_add_alias(arg1,(char const *)arg2,(char const *)arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_clear_alias(void * jarg1, char * jarg2, char * jarg3) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + switch_bool_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + result = (switch_bool_t)switch_live_array_clear_alias(arg1,(char const *)arg2,(char const *)arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_channel_permission_verify(char * jarg1, char * jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + result = (switch_bool_t)switch_event_channel_permission_verify((char const *)arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_event_channel_permission_modify(char * jarg1, char * jarg2, int jarg3) { + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t arg3 ; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_bool_t)jarg3; + switch_event_channel_permission_modify((char const *)arg1,(char const *)arg2,arg3); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_event_channel_permission_clear(char * jarg1) { + char *arg1 = (char *) 0 ; + + arg1 = (char *)jarg1; + switch_event_channel_permission_clear((char const *)arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RESAMPLE_QUALITY_get() { int jresult ; int result; @@ -35304,16 +36723,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_telephony_recv_event(void * ja } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_recv_pt(void * jarg1, unsigned char jarg2) { - switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; - switch_payload_t arg2 ; - - arg1 = (switch_rtp_t *)jarg1; - arg2 = (switch_payload_t)jarg2; - switch_rtp_set_recv_pt(arg1,arg2); -} - - SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_cng_pt(void * jarg1, unsigned char jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_payload_t arg2 ; @@ -35336,6 +36745,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_private(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_set_payload_map(void * jarg1, void * jarg2) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + payload_map_t **arg2 = (payload_map_t **) 0 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + arg2 = (payload_map_t **)jarg2; + result = (switch_status_t)switch_rtp_set_payload_map(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_intentional_bugs(void * jarg1, int jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_rtp_bug_flag_t arg2 ; @@ -35400,6 +36823,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_add_dtls(void * jarg1, void * jarg2 } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_del_dtls(void * jarg1, int jarg2) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + dtls_type_t arg2 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + arg2 = (dtls_type_t)jarg2; + result = (switch_status_t)switch_rtp_del_dtls(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_has_dtls() { int jresult ; int result; @@ -38380,6 +39817,28 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_scheduler_task_cmd_id_get(voi } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_scheduler_task_repeat_set(void * jarg1, unsigned long jarg2) { + switch_scheduler_task *arg1 = (switch_scheduler_task *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_scheduler_task *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->repeat = arg2; +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_scheduler_task_repeat_get(void * jarg1) { + unsigned long jresult ; + switch_scheduler_task *arg1 = (switch_scheduler_task *) 0 ; + uint32_t result; + + arg1 = (switch_scheduler_task *)jarg1; + result = (uint32_t) ((arg1)->repeat); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_scheduler_task_group_set(void * jarg1, char * jarg2) { switch_scheduler_task *arg1 = (switch_scheduler_task *) 0 ; char *arg2 = (char *) 0 ; @@ -38971,11 +40430,13 @@ SWIGEXPORT void SWIGSTDCALL CSharp_IvrMenu_Execute(void * jarg1, void * jarg2, c } -SWIGEXPORT void * SWIGSTDCALL CSharp_new_Api() { +SWIGEXPORT void * SWIGSTDCALL CSharp_new_Api(void * jarg1) { void * jresult ; + CoreSession *arg1 = (CoreSession *) NULL ; API *result = 0 ; - result = (API *)new API(); + arg1 = (CoreSession *)jarg1; + result = (API *)new API(arg1); jresult = (void *)result; return jresult; } diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 3aff242242..44cc42ee90 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -41,7 +41,7 @@ public class Api : IDisposable { } } - public Api() : this(freeswitchPINVOKE.new_Api(), true) { + public Api(CoreSession s) : this(freeswitchPINVOKE.new_Api(CoreSession.getCPtr(s)), true) { } public string Execute(string command, string data) { @@ -1773,6 +1773,11 @@ public class freeswitch { return ret; } + public static string switch_core_get_domain(switch_bool_t dup) { + string ret = freeswitchPINVOKE.switch_core_get_domain((int)dup); + return ret; + } + public static void switch_core_set_variable(string varname, string value) { freeswitchPINVOKE.switch_core_set_variable(varname, value); } @@ -1881,6 +1886,10 @@ public class freeswitch { return ret; } + public static void switch_core_session_video_reset(SWIGTYPE_p_switch_core_session session) { + freeswitchPINVOKE.switch_core_session_video_reset(SWIGTYPE_p_switch_core_session.getCPtr(session)); + } + public static switch_status_t switch_core_session_execute_application_get_flags(SWIGTYPE_p_switch_core_session session, string app, string arg, SWIGTYPE_p_int flags) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_execute_application_get_flags(SWIGTYPE_p_switch_core_session.getCPtr(session), app, arg, SWIGTYPE_p_int.getCPtr(flags)); return ret; @@ -1906,14 +1915,14 @@ public class freeswitch { return ret; } - public static SWIGTYPE_p_void switch_core_session_get_private(SWIGTYPE_p_switch_core_session session) { - IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_private(SWIGTYPE_p_switch_core_session.getCPtr(session)); + public static SWIGTYPE_p_void switch_core_session_get_private_class(SWIGTYPE_p_switch_core_session session, switch_pvt_class_t index) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_private_class(SWIGTYPE_p_switch_core_session.getCPtr(session), (int)index); SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); return ret; } - public static switch_status_t switch_core_session_set_private(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_void private_info) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_set_private(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_void.getCPtr(private_info)); + public static switch_status_t switch_core_session_set_private_class(SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_void private_info, switch_pvt_class_t index) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_set_private_class(SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_void.getCPtr(private_info), (int)index); return ret; } @@ -2353,7 +2362,7 @@ public class freeswitch { freeswitchPINVOKE.switch_core_db_test_reactive(SWIGTYPE_p_sqlite3.getCPtr(db), test_sql, drop_sql, reactive_sql); } - public static switch_status_t switch_core_perform_file_open(string file, string func, int line, switch_file_handle fh, string file_path, byte channels, uint rate, uint flags, SWIGTYPE_p_apr_pool_t pool) { + public static switch_status_t switch_core_perform_file_open(string file, string func, int line, switch_file_handle fh, string file_path, uint channels, uint rate, uint flags, SWIGTYPE_p_apr_pool_t pool) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_perform_file_open(file, func, line, switch_file_handle.getCPtr(fh), file_path, channels, rate, flags, SWIGTYPE_p_apr_pool_t.getCPtr(pool)); return ret; } @@ -3146,6 +3155,11 @@ public class freeswitch { return ret; } + public static switch_call_direction_t switch_ice_direction(SWIGTYPE_p_switch_core_session session) { + switch_call_direction_t ret = (switch_call_direction_t)freeswitchPINVOKE.switch_ice_direction(SWIGTYPE_p_switch_core_session.getCPtr(session)); + return ret; + } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); return ret; @@ -3222,6 +3236,12 @@ public class freeswitch { return ret; } + public static switch_json_api_interface switch_loadable_module_get_json_api_interface(string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_json_api_interface(name); + switch_json_api_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_json_api_interface(cPtr, false); + return ret; + } + public static switch_file_interface switch_loadable_module_get_file_interface(string name) { IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_get_file_interface(name); switch_file_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_file_interface(cPtr, false); @@ -3285,6 +3305,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_json_api_execute(SWIGTYPE_p_cJSON json, SWIGTYPE_p_switch_core_session session, SWIGTYPE_p_p_cJSON retval) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_json_api_execute(SWIGTYPE_p_cJSON.getCPtr(json), SWIGTYPE_p_switch_core_session.getCPtr(session), SWIGTYPE_p_p_cJSON.getCPtr(retval)); + return ret; + } + public static switch_status_t switch_loadable_module_load_module(string dir, string fname, switch_bool_t runtime, ref string err) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_load_module(dir, fname, (int)runtime, ref err); return ret; @@ -3319,6 +3344,21 @@ public class freeswitch { return ret; } + public static SWIGTYPE_p_f_p_switch_core_session__int switch_core_get_secondary_recover_callback(string key) { + IntPtr cPtr = freeswitchPINVOKE.switch_core_get_secondary_recover_callback(key); + SWIGTYPE_p_f_p_switch_core_session__int ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session__int(cPtr, false); + return ret; + } + + public static switch_status_t switch_core_register_secondary_recover_callback(string key, SWIGTYPE_p_f_p_switch_core_session__int cb) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_register_secondary_recover_callback(key, SWIGTYPE_p_f_p_switch_core_session__int.getCPtr(cb)); + return ret; + } + + public static void switch_core_unregister_secondary_recover_callback(string key) { + freeswitchPINVOKE.switch_core_unregister_secondary_recover_callback(key); + } + public static void switch_console_loop() { freeswitchPINVOKE.switch_console_loop(); } @@ -3359,6 +3399,10 @@ public class freeswitch { return ret; } + public static void switch_console_push_match_unique(SWIGTYPE_p_p_switch_console_callback_match matches, string new_val) { + freeswitchPINVOKE.switch_console_push_match_unique(SWIGTYPE_p_p_switch_console_callback_match.getCPtr(matches), new_val); + } + public static void switch_console_push_match(SWIGTYPE_p_p_switch_console_callback_match matches, string new_val) { freeswitchPINVOKE.switch_console_push_match(SWIGTYPE_p_p_switch_console_callback_match.getCPtr(matches), new_val); } @@ -3605,6 +3649,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_find_interface_ip(string buf, int len, SWIGTYPE_p_int mask, string ifname, int family) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_find_interface_ip(buf, len, SWIGTYPE_p_int.getCPtr(mask), ifname, family); + return ret; + } + public static string get_addr(string buf, SWIGTYPE_p_switch_size_t len, SWIGTYPE_p_sockaddr sa, SWIGTYPE_p_socklen_t salen) { string ret = freeswitchPINVOKE.get_addr(buf, SWIGTYPE_p_switch_size_t.getCPtr(len), SWIGTYPE_p_sockaddr.getCPtr(sa), SWIGTYPE_p_socklen_t.getCPtr(salen)); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); @@ -4546,6 +4595,15 @@ public class freeswitch { return ret; } + public static switch_call_direction_t switch_channel_logical_direction(SWIGTYPE_p_switch_channel channel) { + switch_call_direction_t ret = (switch_call_direction_t)freeswitchPINVOKE.switch_channel_logical_direction(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + + public static void switch_channel_set_direction(SWIGTYPE_p_switch_channel channel, switch_call_direction_t direction) { + freeswitchPINVOKE.switch_channel_set_direction(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)direction); + } + public static SWIGTYPE_p_switch_core_session switch_channel_get_session(SWIGTYPE_p_switch_channel channel) { IntPtr cPtr = freeswitchPINVOKE.switch_channel_get_session(SWIGTYPE_p_switch_channel.getCPtr(channel)); SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false); @@ -4911,8 +4969,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_event_binary_deserialize(SWIGTYPE_p_p_switch_event eventp, SWIGTYPE_p_p_void data, SWIGTYPE_p_switch_size_t len, switch_bool_t destroy) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_binary_deserialize(SWIGTYPE_p_p_switch_event.getCPtr(eventp), SWIGTYPE_p_p_void.getCPtr(data), SWIGTYPE_p_switch_size_t.getCPtr(len), (int)destroy); + public static switch_status_t switch_event_binary_deserialize(SWIGTYPE_p_p_switch_event eventp, SWIGTYPE_p_p_void data, SWIGTYPE_p_switch_size_t len, switch_bool_t duplicate) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_binary_deserialize(SWIGTYPE_p_p_switch_event.getCPtr(eventp), SWIGTYPE_p_p_void.getCPtr(data), SWIGTYPE_p_switch_size_t.getCPtr(len), (int)duplicate); if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -4932,6 +4990,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_event_serialize_json_obj(switch_event arg0, SWIGTYPE_p_p_cJSON json) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_serialize_json_obj(switch_event.getCPtr(arg0), SWIGTYPE_p_p_cJSON.getCPtr(json)); + return ret; + } + public static switch_status_t switch_event_create_json(SWIGTYPE_p_p_switch_event arg0, string json) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_create_json(SWIGTYPE_p_p_switch_event.getCPtr(arg0), json); return ret; @@ -4990,10 +5053,124 @@ public class freeswitch { freeswitchPINVOKE.switch_event_add_presence_data_cols(SWIGTYPE_p_switch_channel.getCPtr(channel), switch_event.getCPtr(arg1), prefix); } + public static void switch_json_add_presence_data_cols(switch_event arg0, SWIGTYPE_p_cJSON json, string prefix) { + freeswitchPINVOKE.switch_json_add_presence_data_cols(switch_event.getCPtr(arg0), SWIGTYPE_p_cJSON.getCPtr(json), prefix); + } + public static void switch_event_launch_dispatch_threads(uint max) { freeswitchPINVOKE.switch_event_launch_dispatch_threads(max); } + public static uint switch_event_channel_broadcast(string event_channel, SWIGTYPE_p_p_cJSON json, string key, uint id) { + uint ret = freeswitchPINVOKE.switch_event_channel_broadcast(event_channel, SWIGTYPE_p_p_cJSON.getCPtr(json), key, id); + return ret; + } + + public static uint switch_event_channel_unbind(string event_channel, SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void func) { + uint ret = freeswitchPINVOKE.switch_event_channel_unbind(event_channel, SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void.getCPtr(func)); + return ret; + } + + public static switch_status_t switch_event_channel_bind(string event_channel, SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void func, SWIGTYPE_p_unsigned_long id) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_event_channel_bind(event_channel, SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void.getCPtr(func), SWIGTYPE_p_unsigned_long.getCPtr(id)); + return ret; + } + + public static switch_status_t switch_live_array_clear(SWIGTYPE_p_switch_live_array_s la) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_live_array_clear(SWIGTYPE_p_switch_live_array_s.getCPtr(la)); + return ret; + } + + public static switch_status_t switch_live_array_bootstrap(SWIGTYPE_p_switch_live_array_s la, string sessid, uint channel_id) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_live_array_bootstrap(SWIGTYPE_p_switch_live_array_s.getCPtr(la), sessid, channel_id); + return ret; + } + + public static switch_status_t switch_live_array_destroy(SWIGTYPE_p_p_switch_live_array_s live_arrayP) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_live_array_destroy(SWIGTYPE_p_p_switch_live_array_s.getCPtr(live_arrayP)); + return ret; + } + + public static switch_status_t switch_live_array_create(string event_channel, string name, uint channel_id, SWIGTYPE_p_p_switch_live_array_s live_arrayP) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_live_array_create(event_channel, name, channel_id, SWIGTYPE_p_p_switch_live_array_s.getCPtr(live_arrayP)); + return ret; + } + + public static SWIGTYPE_p_cJSON switch_live_array_get(SWIGTYPE_p_switch_live_array_s la, string name) { + IntPtr cPtr = freeswitchPINVOKE.switch_live_array_get(SWIGTYPE_p_switch_live_array_s.getCPtr(la), name); + SWIGTYPE_p_cJSON ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_cJSON(cPtr, false); + return ret; + } + + public static SWIGTYPE_p_cJSON switch_live_array_get_idx(SWIGTYPE_p_switch_live_array_s la, int idx) { + IntPtr cPtr = freeswitchPINVOKE.switch_live_array_get_idx(SWIGTYPE_p_switch_live_array_s.getCPtr(la), idx); + SWIGTYPE_p_cJSON ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_cJSON(cPtr, false); + return ret; + } + + public static switch_status_t switch_live_array_del(SWIGTYPE_p_switch_live_array_s la, string name) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_live_array_del(SWIGTYPE_p_switch_live_array_s.getCPtr(la), name); + return ret; + } + + public static switch_status_t switch_live_array_add(SWIGTYPE_p_switch_live_array_s la, string name, int index, SWIGTYPE_p_p_cJSON obj, switch_bool_t destroy) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_live_array_add(SWIGTYPE_p_switch_live_array_s.getCPtr(la), name, index, SWIGTYPE_p_p_cJSON.getCPtr(obj), (int)destroy); + return ret; + } + + public static switch_status_t switch_live_array_visible(SWIGTYPE_p_switch_live_array_s la, switch_bool_t visible, switch_bool_t force) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_live_array_visible(SWIGTYPE_p_switch_live_array_s.getCPtr(la), (int)visible, (int)force); + return ret; + } + + public static switch_bool_t switch_live_array_isnew(SWIGTYPE_p_switch_live_array_s la) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_live_array_isnew(SWIGTYPE_p_switch_live_array_s.getCPtr(la)); + return ret; + } + + public static void switch_live_array_lock(SWIGTYPE_p_switch_live_array_s la) { + freeswitchPINVOKE.switch_live_array_lock(SWIGTYPE_p_switch_live_array_s.getCPtr(la)); + } + + public static void switch_live_array_unlock(SWIGTYPE_p_switch_live_array_s la) { + freeswitchPINVOKE.switch_live_array_unlock(SWIGTYPE_p_switch_live_array_s.getCPtr(la)); + } + + public static void switch_live_array_set_user_data(SWIGTYPE_p_switch_live_array_s la, SWIGTYPE_p_void user_data) { + freeswitchPINVOKE.switch_live_array_set_user_data(SWIGTYPE_p_switch_live_array_s.getCPtr(la), SWIGTYPE_p_void.getCPtr(user_data)); + } + + public static void switch_live_array_set_command_handler(SWIGTYPE_p_switch_live_array_s la, SWIGTYPE_p_f_p_switch_live_array_s_p_q_const__char_p_q_const__char_p_cJSON_p_void__void command_handler) { + freeswitchPINVOKE.switch_live_array_set_command_handler(SWIGTYPE_p_switch_live_array_s.getCPtr(la), SWIGTYPE_p_f_p_switch_live_array_s_p_q_const__char_p_q_const__char_p_cJSON_p_void__void.getCPtr(command_handler)); + } + + public static void switch_live_array_parse_json(SWIGTYPE_p_cJSON json, uint channel_id) { + freeswitchPINVOKE.switch_live_array_parse_json(SWIGTYPE_p_cJSON.getCPtr(json), channel_id); + } + + public static switch_bool_t switch_live_array_add_alias(SWIGTYPE_p_switch_live_array_s la, string event_channel, string name) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_live_array_add_alias(SWIGTYPE_p_switch_live_array_s.getCPtr(la), event_channel, name); + return ret; + } + + public static switch_bool_t switch_live_array_clear_alias(SWIGTYPE_p_switch_live_array_s la, string event_channel, string name) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_live_array_clear_alias(SWIGTYPE_p_switch_live_array_s.getCPtr(la), event_channel, name); + return ret; + } + + public static switch_bool_t switch_event_channel_permission_verify(string cookie, string event_channel) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_event_channel_permission_verify(cookie, event_channel); + return ret; + } + + public static void switch_event_channel_permission_modify(string cookie, string event_channel, switch_bool_t set) { + freeswitchPINVOKE.switch_event_channel_permission_modify(cookie, event_channel, (int)set); + } + + public static void switch_event_channel_permission_clear(string cookie) { + freeswitchPINVOKE.switch_event_channel_permission_clear(cookie); + } + public static switch_status_t switch_resample_perform_create(SWIGTYPE_p_p_switch_audio_resampler_t new_resampler, uint from_rate, uint to_rate, uint to_size, int quality, uint channels, string file, string func, int line) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_resample_perform_create(SWIGTYPE_p_p_switch_audio_resampler_t.getCPtr(new_resampler), from_rate, to_rate, to_size, quality, channels, file, func, line); return ret; @@ -6062,10 +6239,6 @@ public class freeswitch { freeswitchPINVOKE.switch_rtp_set_telephony_recv_event(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), te); } - public static void switch_rtp_set_recv_pt(SWIGTYPE_p_switch_rtp rtp_session, byte pt) { - freeswitchPINVOKE.switch_rtp_set_recv_pt(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), pt); - } - public static void switch_rtp_set_cng_pt(SWIGTYPE_p_switch_rtp rtp_session, byte pt) { freeswitchPINVOKE.switch_rtp_set_cng_pt(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), pt); } @@ -6076,6 +6249,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_rtp_set_payload_map(SWIGTYPE_p_switch_rtp rtp_session, SWIGTYPE_p_p_payload_map_t pmap) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_set_payload_map(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), SWIGTYPE_p_p_payload_map_t.getCPtr(pmap)); + return ret; + } + public static void switch_rtp_intentional_bugs(SWIGTYPE_p_switch_rtp rtp_session, switch_rtp_bug_flag_t bugs) { freeswitchPINVOKE.switch_rtp_intentional_bugs(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)bugs); } @@ -6100,6 +6278,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_rtp_del_dtls(SWIGTYPE_p_switch_rtp rtp_session, dtls_type_t type) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_del_dtls(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)type); + return ret; + } + public static int switch_rtp_has_dtls() { int ret = freeswitchPINVOKE.switch_rtp_has_dtls(); return ret; @@ -6814,6 +6997,7 @@ public class freeswitch { public static readonly int SWITCH_DEFAULT_FILE_BUFFER_LEN = freeswitchPINVOKE.SWITCH_DEFAULT_FILE_BUFFER_LEN_get(); public static readonly int SWITCH_DTMF_LOG_LEN = freeswitchPINVOKE.SWITCH_DTMF_LOG_LEN_get(); public static readonly int SWITCH_MAX_TRANS = freeswitchPINVOKE.SWITCH_MAX_TRANS_get(); + public static readonly int SWITCH_CORE_SESSION_MAX_PRIVATES = freeswitchPINVOKE.SWITCH_CORE_SESSION_MAX_PRIVATES_get(); public static readonly int SWITCH_MAX_STACKS = freeswitchPINVOKE.SWITCH_MAX_STACKS_get(); public static readonly int SWITCH_THREAD_STACKSIZE = freeswitchPINVOKE.SWITCH_THREAD_STACKSIZE_get(); public static readonly int SWITCH_SYSTEM_THREAD_STACKSIZE = freeswitchPINVOKE.SWITCH_SYSTEM_THREAD_STACKSIZE_get(); @@ -6870,6 +7054,8 @@ public class freeswitch { public static readonly int SWITCH_CMD_CHUNK_LEN = freeswitchPINVOKE.SWITCH_CMD_CHUNK_LEN_get(); public static readonly int SWITCH_SMAX = freeswitchPINVOKE.SWITCH_SMAX_get(); public static readonly int SWITCH_SMIN = freeswitchPINVOKE.SWITCH_SMIN_get(); + public static readonly int NO_EVENT_CHANNEL_ID = freeswitchPINVOKE.NO_EVENT_CHANNEL_ID_get(); + public static readonly string SWITCH_EVENT_CHANNEL_GLOBAL = freeswitchPINVOKE.SWITCH_EVENT_CHANNEL_GLOBAL_get(); public static readonly int SWITCH_RESAMPLE_QUALITY = freeswitchPINVOKE.SWITCH_RESAMPLE_QUALITY_get(); public static readonly int SWITCH_RTP_MAX_BUF_LEN = freeswitchPINVOKE.SWITCH_RTP_MAX_BUF_LEN_get(); public static readonly int SWITCH_RTCP_MAX_BUF_LEN = freeswitchPINVOKE.SWITCH_RTCP_MAX_BUF_LEN_get(); @@ -7561,6 +7747,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_MAX_TRANS_get")] public static extern int SWITCH_MAX_TRANS_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CORE_SESSION_MAX_PRIVATES_get")] + public static extern int SWITCH_CORE_SESSION_MAX_PRIVATES_get(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_dtmf_t_digit_set")] public static extern void switch_dtmf_t_digit_set(HandleRef jarg1, char jarg2); @@ -8683,6 +8872,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_alloc_get")] public static extern int switch_thread_data_t_alloc_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_pool_set")] + public static extern void switch_thread_data_t_pool_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_thread_data_t_pool_get")] + public static extern IntPtr switch_thread_data_t_pool_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_thread_data_t")] public static extern IntPtr new_switch_thread_data_t(); @@ -8755,6 +8950,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_hup_profile_get")] public static extern IntPtr switch_device_node_t_hup_profile_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_direction_set")] + public static extern void switch_device_node_t_direction_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_direction_get")] + public static extern int switch_device_node_t_direction_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_parent_set")] public static extern void switch_device_node_t_parent_set(HandleRef jarg1, HandleRef jarg2); @@ -8779,42 +8980,132 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_get")] public static extern uint switch_device_stats_t_total_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_in_set")] + public static extern void switch_device_stats_t_total_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_in_get")] + public static extern uint switch_device_stats_t_total_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_out_set")] + public static extern void switch_device_stats_t_total_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_out_get")] + public static extern uint switch_device_stats_t_total_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_set")] public static extern void switch_device_stats_t_offhook_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_get")] public static extern uint switch_device_stats_t_offhook_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_in_set")] + public static extern void switch_device_stats_t_offhook_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_in_get")] + public static extern uint switch_device_stats_t_offhook_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_out_set")] + public static extern void switch_device_stats_t_offhook_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_out_get")] + public static extern uint switch_device_stats_t_offhook_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_set")] public static extern void switch_device_stats_t_active_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_get")] public static extern uint switch_device_stats_t_active_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_in_set")] + public static extern void switch_device_stats_t_active_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_in_get")] + public static extern uint switch_device_stats_t_active_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_out_set")] + public static extern void switch_device_stats_t_active_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_out_get")] + public static extern uint switch_device_stats_t_active_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_set")] public static extern void switch_device_stats_t_held_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_get")] public static extern uint switch_device_stats_t_held_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_in_set")] + public static extern void switch_device_stats_t_held_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_in_get")] + public static extern uint switch_device_stats_t_held_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_out_set")] + public static extern void switch_device_stats_t_held_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_out_get")] + public static extern uint switch_device_stats_t_held_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_set")] public static extern void switch_device_stats_t_hup_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_get")] public static extern uint switch_device_stats_t_hup_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_in_set")] + public static extern void switch_device_stats_t_hup_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_in_get")] + public static extern uint switch_device_stats_t_hup_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_out_set")] + public static extern void switch_device_stats_t_hup_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_out_get")] + public static extern uint switch_device_stats_t_hup_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_set")] public static extern void switch_device_stats_t_ringing_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_get")] public static extern uint switch_device_stats_t_ringing_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_in_set")] + public static extern void switch_device_stats_t_ringing_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_in_get")] + public static extern uint switch_device_stats_t_ringing_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_out_set")] + public static extern void switch_device_stats_t_ringing_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_out_get")] + public static extern uint switch_device_stats_t_ringing_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_set")] public static extern void switch_device_stats_t_early_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_get")] public static extern uint switch_device_stats_t_early_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_in_set")] + public static extern void switch_device_stats_t_early_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_in_get")] + public static extern uint switch_device_stats_t_early_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_out_set")] + public static extern void switch_device_stats_t_early_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_out_get")] + public static extern uint switch_device_stats_t_early_out_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ring_wait_set")] + public static extern void switch_device_stats_t_ring_wait_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ring_wait_get")] + public static extern uint switch_device_stats_t_ring_wait_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_device_stats_t")] public static extern IntPtr new_switch_device_stats_t(); @@ -8845,6 +9136,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_stats_get")] public static extern IntPtr switch_device_record_t_stats_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_last_stats_set")] + public static extern void switch_device_record_t_last_stats_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_last_stats_get")] + public static extern IntPtr switch_device_record_t_last_stats_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_state_set")] public static extern void switch_device_record_t_state_set(HandleRef jarg1, int jarg2); @@ -8875,6 +9172,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_last_call_time_get")] public static extern IntPtr switch_device_record_t_last_call_time_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_start_set")] + public static extern void switch_device_record_t_ring_start_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_start_get")] + public static extern IntPtr switch_device_record_t_ring_start_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_stop_set")] + public static extern void switch_device_record_t_ring_stop_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_stop_get")] + public static extern IntPtr switch_device_record_t_ring_stop_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_start_set")] + public static extern void switch_device_record_t_hold_start_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_start_get")] + public static extern IntPtr switch_device_record_t_hold_start_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_stop_set")] + public static extern void switch_device_record_t_hold_stop_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_stop_get")] + public static extern IntPtr switch_device_record_t_hold_stop_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_call_start_set")] + public static extern void switch_device_record_t_call_start_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_call_start_get")] + public static extern IntPtr switch_device_record_t_call_start_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_uuid_list_set")] public static extern void switch_device_record_t_uuid_list_set(HandleRef jarg1, HandleRef jarg2); @@ -8899,6 +9226,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_pool_get")] public static extern IntPtr switch_device_record_t_pool_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_user_data_set")] + public static extern void switch_device_record_t_user_data_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_user_data_get")] + public static extern IntPtr switch_device_record_t_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_device_record_t")] public static extern IntPtr new_switch_device_record_t(); @@ -9439,6 +9772,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_switchname")] public static extern string switch_core_get_switchname(); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_domain")] + public static extern string switch_core_get_domain(int jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_set_variable")] public static extern void switch_core_set_variable(string jarg1, string jarg2); @@ -9505,6 +9841,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_exec")] public static extern int switch_core_session_exec(HandleRef jarg1, HandleRef jarg2, string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_video_reset")] + public static extern void switch_core_session_video_reset(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_execute_application_get_flags")] public static extern int switch_core_session_execute_application_get_flags(HandleRef jarg1, string jarg2, string jarg3, HandleRef jarg4); @@ -9520,11 +9859,11 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_receive_event")] public static extern int switch_core_session_receive_event(HandleRef jarg1, HandleRef jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_private")] - public static extern IntPtr switch_core_session_get_private(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_private_class")] + public static extern IntPtr switch_core_session_get_private_class(HandleRef jarg1, int jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_private")] - public static extern int switch_core_session_set_private(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_private_class")] + public static extern int switch_core_session_set_private_class(HandleRef jarg1, HandleRef jarg2, int jarg3); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_add_stream")] public static extern int switch_core_session_add_stream(HandleRef jarg1, HandleRef jarg2); @@ -9788,7 +10127,7 @@ class freeswitchPINVOKE { public static extern void switch_core_db_test_reactive(HandleRef jarg1, string jarg2, string jarg3, string jarg4); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_perform_file_open")] - public static extern int switch_core_perform_file_open(string jarg1, string jarg2, int jarg3, HandleRef jarg4, string jarg5, byte jarg6, uint jarg7, uint jarg8, HandleRef jarg9); + public static extern int switch_core_perform_file_open(string jarg1, string jarg2, int jarg3, HandleRef jarg4, string jarg5, uint jarg6, uint jarg7, uint jarg8, HandleRef jarg9); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_file_read")] public static extern int switch_core_file_read(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); @@ -10381,6 +10720,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_stream_system_fork")] public static extern int switch_stream_system_fork(string jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ice_direction")] + public static extern int switch_ice_direction(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); @@ -10429,6 +10771,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_api_interface_get")] public static extern IntPtr switch_loadable_module_interface_api_interface_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_json_api_interface_set")] + public static extern void switch_loadable_module_interface_json_api_interface_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_json_api_interface_get")] + public static extern IntPtr switch_loadable_module_interface_json_api_interface_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_file_interface_set")] public static extern void switch_loadable_module_interface_file_interface_set(HandleRef jarg1, HandleRef jarg2); @@ -10543,6 +10891,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_api_interface")] public static extern IntPtr switch_loadable_module_get_api_interface(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_json_api_interface")] + public static extern IntPtr switch_loadable_module_get_json_api_interface(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_file_interface")] public static extern IntPtr switch_loadable_module_get_file_interface(string jarg1); @@ -10576,6 +10927,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_api_execute")] public static extern int switch_api_execute(string jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_execute")] + public static extern int switch_json_api_execute(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_load_module")] public static extern int switch_loadable_module_load_module(string jarg1, string jarg2, int jarg3, ref string jarg4); @@ -10597,6 +10951,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_ready")] public static extern int switch_core_codec_ready(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_secondary_recover_callback")] + public static extern IntPtr switch_core_get_secondary_recover_callback(string jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_register_secondary_recover_callback")] + public static extern int switch_core_register_secondary_recover_callback(string jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_unregister_secondary_recover_callback")] + public static extern void switch_core_unregister_secondary_recover_callback(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_CMD_CHUNK_LEN_get")] public static extern int SWITCH_CMD_CHUNK_LEN_get(); @@ -10624,6 +10987,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_console_run_complete_func")] public static extern int switch_console_run_complete_func(string jarg1, string jarg2, string jarg3, HandleRef jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_console_push_match_unique")] + public static extern void switch_console_push_match_unique(HandleRef jarg1, string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_console_push_match")] public static extern void switch_console_push_match(HandleRef jarg1, string jarg2); @@ -10795,6 +11161,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_find_local_ip")] public static extern int switch_find_local_ip(string jarg1, int jarg2, HandleRef jarg3, int jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_find_interface_ip")] + public static extern int switch_find_interface_ip(string jarg1, int jarg2, HandleRef jarg3, string jarg4, int jarg5); + [DllImport("mod_managed", EntryPoint="CSharp_get_addr")] public static extern string get_addr(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4); @@ -11242,6 +11611,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_direction_get")] public static extern int switch_caller_profile_direction_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_logical_direction_set")] + public static extern void switch_caller_profile_logical_direction_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_logical_direction_get")] + public static extern int switch_caller_profile_logical_direction_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_soft_set")] public static extern void switch_caller_profile_soft_set(HandleRef jarg1, HandleRef jarg2); @@ -11479,6 +11854,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_user_data_get")] public static extern IntPtr switch_frame_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_pmap_set")] + public static extern void switch_frame_pmap_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_pmap_get")] + public static extern IntPtr switch_frame_pmap_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_frame")] public static extern IntPtr new_switch_frame(); @@ -12116,10 +12497,10 @@ class freeswitchPINVOKE { public static extern uint switch_file_handle_native_rate_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle_channels_set")] - public static extern void switch_file_handle_channels_set(HandleRef jarg1, byte jarg2); + public static extern void switch_file_handle_channels_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle_channels_get")] - public static extern byte switch_file_handle_channels_get(HandleRef jarg1); + public static extern uint switch_file_handle_channels_get(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle_format_set")] public static extern void switch_file_handle_format_set(HandleRef jarg1, uint jarg2); @@ -12325,6 +12706,18 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle__params_get")] public static extern IntPtr switch_file_handle__params_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle_cur_channels_set")] + public static extern void switch_file_handle_cur_channels_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle_cur_channels_get")] + public static extern uint switch_file_handle_cur_channels_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle_cur_samplerate_set")] + public static extern void switch_file_handle_cur_samplerate_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_file_handle_cur_samplerate_get")] + public static extern uint switch_file_handle_cur_samplerate_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_file_handle")] public static extern IntPtr new_switch_file_handle(); @@ -13615,6 +14008,66 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_api_interface")] public static extern void delete_switch_api_interface(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_interface_name_set")] + public static extern void switch_json_api_interface_interface_name_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_interface_name_get")] + public static extern string switch_json_api_interface_interface_name_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_desc_set")] + public static extern void switch_json_api_interface_desc_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_desc_get")] + public static extern string switch_json_api_interface_desc_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_function_set")] + public static extern void switch_json_api_interface_function_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_function_get")] + public static extern IntPtr switch_json_api_interface_function_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_syntax_set")] + public static extern void switch_json_api_interface_syntax_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_syntax_get")] + public static extern string switch_json_api_interface_syntax_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_rwlock_set")] + public static extern void switch_json_api_interface_rwlock_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_rwlock_get")] + public static extern IntPtr switch_json_api_interface_rwlock_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_refs_set")] + public static extern void switch_json_api_interface_refs_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_refs_get")] + public static extern int switch_json_api_interface_refs_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_reflock_set")] + public static extern void switch_json_api_interface_reflock_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_reflock_get")] + public static extern IntPtr switch_json_api_interface_reflock_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_parent_set")] + public static extern void switch_json_api_interface_parent_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_parent_get")] + public static extern IntPtr switch_json_api_interface_parent_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_next_set")] + public static extern void switch_json_api_interface_next_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_api_interface_next_get")] + public static extern IntPtr switch_json_api_interface_next_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_json_api_interface")] + public static extern IntPtr new_switch_json_api_interface(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_json_api_interface")] + public static extern void delete_switch_json_api_interface(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_set")] public static extern void switch_slin_data_session_set(HandleRef jarg1, HandleRef jarg2); @@ -14071,6 +14524,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_direction")] public static extern int switch_channel_direction(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_logical_direction")] + public static extern int switch_channel_logical_direction(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_direction")] + public static extern void switch_channel_set_direction(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_session")] public static extern IntPtr switch_channel_get_session(HandleRef jarg1); @@ -14485,6 +14944,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_event_serialize_json")] public static extern int switch_event_serialize_json(HandleRef jarg1, ref string jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_serialize_json_obj")] + public static extern int switch_event_serialize_json_obj(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_create_json")] public static extern int switch_event_create_json(HandleRef jarg1, string jarg2); @@ -14521,9 +14983,87 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_event_add_presence_data_cols")] public static extern void switch_event_add_presence_data_cols(HandleRef jarg1, HandleRef jarg2, string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_json_add_presence_data_cols")] + public static extern void switch_json_add_presence_data_cols(HandleRef jarg1, HandleRef jarg2, string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_launch_dispatch_threads")] public static extern void switch_event_launch_dispatch_threads(uint jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_broadcast")] + public static extern uint switch_event_channel_broadcast(string jarg1, HandleRef jarg2, string jarg3, uint jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_unbind")] + public static extern uint switch_event_channel_unbind(string jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_bind")] + public static extern int switch_event_channel_bind(string jarg1, HandleRef jarg2, HandleRef jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_NO_EVENT_CHANNEL_ID_get")] + public static extern int NO_EVENT_CHANNEL_ID_get(); + + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_EVENT_CHANNEL_GLOBAL_get")] + public static extern string SWITCH_EVENT_CHANNEL_GLOBAL_get(); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_clear")] + public static extern int switch_live_array_clear(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_bootstrap")] + public static extern int switch_live_array_bootstrap(HandleRef jarg1, string jarg2, uint jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_destroy")] + public static extern int switch_live_array_destroy(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_create")] + public static extern int switch_live_array_create(string jarg1, string jarg2, uint jarg3, HandleRef jarg4); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_get")] + public static extern IntPtr switch_live_array_get(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_get_idx")] + public static extern IntPtr switch_live_array_get_idx(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_del")] + public static extern int switch_live_array_del(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_add")] + public static extern int switch_live_array_add(HandleRef jarg1, string jarg2, int jarg3, HandleRef jarg4, int jarg5); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_visible")] + public static extern int switch_live_array_visible(HandleRef jarg1, int jarg2, int jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_isnew")] + public static extern int switch_live_array_isnew(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_lock")] + public static extern void switch_live_array_lock(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_unlock")] + public static extern void switch_live_array_unlock(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_set_user_data")] + public static extern void switch_live_array_set_user_data(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_set_command_handler")] + public static extern void switch_live_array_set_command_handler(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_parse_json")] + public static extern void switch_live_array_parse_json(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_add_alias")] + public static extern int switch_live_array_add_alias(HandleRef jarg1, string jarg2, string jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_clear_alias")] + public static extern int switch_live_array_clear_alias(HandleRef jarg1, string jarg2, string jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_permission_verify")] + public static extern int switch_event_channel_permission_verify(string jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_permission_modify")] + public static extern void switch_event_channel_permission_modify(string jarg1, string jarg2, int jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_permission_clear")] + public static extern void switch_event_channel_permission_clear(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RESAMPLE_QUALITY_get")] public static extern int SWITCH_RESAMPLE_QUALITY_get(); @@ -15511,15 +16051,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_telephony_recv_event")] public static extern void switch_rtp_set_telephony_recv_event(HandleRef jarg1, byte jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_recv_pt")] - public static extern void switch_rtp_set_recv_pt(HandleRef jarg1, byte jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_cng_pt")] public static extern void switch_rtp_set_cng_pt(HandleRef jarg1, byte jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_private")] public static extern IntPtr switch_rtp_get_private(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_payload_map")] + public static extern int switch_rtp_set_payload_map(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_intentional_bugs")] public static extern void switch_rtp_intentional_bugs(HandleRef jarg1, int jarg2); @@ -15535,6 +16075,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_add_dtls")] public static extern int switch_rtp_add_dtls(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, int jarg4); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_del_dtls")] + public static extern int switch_rtp_del_dtls(HandleRef jarg1, int jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_has_dtls")] public static extern int switch_rtp_has_dtls(); @@ -16264,6 +16807,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_scheduler_task_cmd_id_get")] public static extern uint switch_scheduler_task_cmd_id_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_scheduler_task_repeat_set")] + public static extern void switch_scheduler_task_repeat_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_scheduler_task_repeat_get")] + public static extern uint switch_scheduler_task_repeat_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_scheduler_task_group_set")] public static extern void switch_scheduler_task_group_set(HandleRef jarg1, string jarg2); @@ -16403,7 +16952,7 @@ class freeswitchPINVOKE { public static extern void IvrMenu_Execute(HandleRef jarg1, HandleRef jarg2, string jarg3); [DllImport("mod_managed", EntryPoint="CSharp_new_Api")] - public static extern IntPtr new_Api(); + public static extern IntPtr new_Api(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_delete_Api")] public static extern void delete_Api(HandleRef jarg1); @@ -17624,6 +18173,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_cJSON { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_cJSON(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_cJSON() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_cJSON obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_FILE { private HandleRef swigCPtr; @@ -17744,6 +18323,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_q_const__char_p_cJSON_p_q_const__char_unsigned_long__void obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_q_const__char_p_q_const__char_p_p_switch_console_callback_match__switch_status_t { private HandleRef swigCPtr; @@ -17954,6 +18563,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_q_const__switch_log_node_t_enum_switch_log_level_t__switch_status_t { private HandleRef swigCPtr; @@ -19634,6 +20273,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_live_array_s_p_q_const__char_p_q_const__char_p_cJSON_p_void__void { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_live_array_s_p_q_const__char_p_q_const__char_p_cJSON_p_void__void(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_live_array_s_p_q_const__char_p_q_const__char_p_cJSON_p_void__void() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_live_array_s_p_q_const__char_p_q_const__char_p_cJSON_p_void__void obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_f_p_switch_media_bug_p_void_enum_switch_abc_type_t__switch_bool_t { private HandleRef swigCPtr; @@ -20444,6 +21113,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_payload_map_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_payload_map_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_payload_map_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_payload_map_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_pid_t { private HandleRef swigCPtr; @@ -20564,6 +21263,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_payload_map_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_payload_map_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_payload_map_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_payload_map_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_p_char { private HandleRef swigCPtr; @@ -21344,6 +22073,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_switch_live_array_s { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_switch_live_array_s(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_switch_live_array_s() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_switch_live_array_s obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_switch_log_node_t { private HandleRef swigCPtr; @@ -22394,6 +23153,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_live_array_s { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_live_array_s(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_live_array_s() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_live_array_s obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_media_bug { private HandleRef swigCPtr; @@ -25573,6 +26362,16 @@ public class switch_caller_profile : IDisposable { } } + public switch_call_direction_t logical_direction { + set { + freeswitchPINVOKE.switch_caller_profile_logical_direction_set(swigCPtr, (int)value); + } + get { + switch_call_direction_t ret = (switch_call_direction_t)freeswitchPINVOKE.switch_caller_profile_logical_direction_get(swigCPtr); + return ret; + } + } + public profile_node_t soft { set { freeswitchPINVOKE.switch_caller_profile_soft_set(swigCPtr, profile_node_t.getCPtr(value)); @@ -25773,6 +26572,7 @@ public enum switch_channel_callstate_t { CCS_EARLY, CCS_ACTIVE, CCS_HELD, + CCS_RING_WAIT, CCS_HANGUP, CCS_UNHOLD } @@ -25892,6 +26692,7 @@ public enum switch_channel_flag_t { CF_CONFIRM_BLIND_TRANSFER, CF_NO_PRESENCE, CF_CONFERENCE, + CF_CONFERENCE_ADV, CF_RECOVERING, CF_RECOVERING_BRIDGE, CF_TRACKED, @@ -25923,6 +26724,8 @@ public enum switch_channel_flag_t { CF_VIDEO_PASSIVE, CF_NOVIDEO, CF_VIDEO_ECHO, + CF_SLA_INTERCEPT, + CF_VIDEO_BREAK, CF_FLAG_MAX } @@ -27868,6 +28671,10 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE, SWITCH_MESSAGE_INDICATE_STUN_ERROR, SWITCH_MESSAGE_INDICATE_MEDIA_RENEG, + SWITCH_MESSAGE_REFER_EVENT, + SWITCH_MESSAGE_ANSWER_EVENT, + SWITCH_MESSAGE_PROGRESS_EVENT, + SWITCH_MESSAGE_RING_EVENT, SWITCH_MESSAGE_INVALID } @@ -28201,6 +29008,16 @@ public class switch_device_node_t : IDisposable { } } + public switch_call_direction_t direction { + set { + freeswitchPINVOKE.switch_device_node_t_direction_set(swigCPtr, (int)value); + } + get { + switch_call_direction_t ret = (switch_call_direction_t)freeswitchPINVOKE.switch_device_node_t_direction_get(swigCPtr); + return ret; + } + } + public switch_device_record_t parent { set { freeswitchPINVOKE.switch_device_node_t_parent_set(swigCPtr, switch_device_record_t.getCPtr(value)); @@ -28313,6 +29130,17 @@ public class switch_device_record_t : IDisposable { } } + public switch_device_stats_t last_stats { + set { + freeswitchPINVOKE.switch_device_record_t_last_stats_set(swigCPtr, switch_device_stats_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_device_record_t_last_stats_get(swigCPtr); + switch_device_stats_t ret = (cPtr == IntPtr.Zero) ? null : new switch_device_stats_t(cPtr, false); + return ret; + } + } + public switch_device_state_t state { set { freeswitchPINVOKE.switch_device_record_t_state_set(swigCPtr, (int)value); @@ -28369,6 +29197,66 @@ public class switch_device_record_t : IDisposable { } } + public SWIGTYPE_p_switch_time_t ring_start { + set { + freeswitchPINVOKE.switch_device_record_t_ring_start_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_ring_start_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t ring_stop { + set { + freeswitchPINVOKE.switch_device_record_t_ring_stop_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_ring_stop_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t hold_start { + set { + freeswitchPINVOKE.switch_device_record_t_hold_start_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_hold_start_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t hold_stop { + set { + freeswitchPINVOKE.switch_device_record_t_hold_stop_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_hold_stop_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t call_start { + set { + freeswitchPINVOKE.switch_device_record_t_call_start_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_call_start_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + public switch_device_node_t uuid_list { set { freeswitchPINVOKE.switch_device_record_t_uuid_list_set(swigCPtr, switch_device_node_t.getCPtr(value)); @@ -28413,6 +29301,17 @@ public class switch_device_record_t : IDisposable { } } + public SWIGTYPE_p_void user_data { + set { + freeswitchPINVOKE.switch_device_record_t_user_data_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_device_record_t_user_data_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + public switch_device_record_t() : this(freeswitchPINVOKE.new_switch_device_record_t(), true) { } @@ -28492,6 +29391,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint total_in { + set { + freeswitchPINVOKE.switch_device_stats_t_total_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_total_in_get(swigCPtr); + return ret; + } + } + + public uint total_out { + set { + freeswitchPINVOKE.switch_device_stats_t_total_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_total_out_get(swigCPtr); + return ret; + } + } + public uint offhook { set { freeswitchPINVOKE.switch_device_stats_t_offhook_set(swigCPtr, value); @@ -28502,6 +29421,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint offhook_in { + set { + freeswitchPINVOKE.switch_device_stats_t_offhook_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_offhook_in_get(swigCPtr); + return ret; + } + } + + public uint offhook_out { + set { + freeswitchPINVOKE.switch_device_stats_t_offhook_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_offhook_out_get(swigCPtr); + return ret; + } + } + public uint active { set { freeswitchPINVOKE.switch_device_stats_t_active_set(swigCPtr, value); @@ -28512,6 +29451,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint active_in { + set { + freeswitchPINVOKE.switch_device_stats_t_active_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_active_in_get(swigCPtr); + return ret; + } + } + + public uint active_out { + set { + freeswitchPINVOKE.switch_device_stats_t_active_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_active_out_get(swigCPtr); + return ret; + } + } + public uint held { set { freeswitchPINVOKE.switch_device_stats_t_held_set(swigCPtr, value); @@ -28522,6 +29481,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint held_in { + set { + freeswitchPINVOKE.switch_device_stats_t_held_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_held_in_get(swigCPtr); + return ret; + } + } + + public uint held_out { + set { + freeswitchPINVOKE.switch_device_stats_t_held_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_held_out_get(swigCPtr); + return ret; + } + } + public uint hup { set { freeswitchPINVOKE.switch_device_stats_t_hup_set(swigCPtr, value); @@ -28532,6 +29511,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint hup_in { + set { + freeswitchPINVOKE.switch_device_stats_t_hup_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_hup_in_get(swigCPtr); + return ret; + } + } + + public uint hup_out { + set { + freeswitchPINVOKE.switch_device_stats_t_hup_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_hup_out_get(swigCPtr); + return ret; + } + } + public uint ringing { set { freeswitchPINVOKE.switch_device_stats_t_ringing_set(swigCPtr, value); @@ -28542,6 +29541,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint ringing_in { + set { + freeswitchPINVOKE.switch_device_stats_t_ringing_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_ringing_in_get(swigCPtr); + return ret; + } + } + + public uint ringing_out { + set { + freeswitchPINVOKE.switch_device_stats_t_ringing_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_ringing_out_get(swigCPtr); + return ret; + } + } + public uint early { set { freeswitchPINVOKE.switch_device_stats_t_early_set(swigCPtr, value); @@ -28552,6 +29571,36 @@ public class switch_device_stats_t : IDisposable { } } + public uint early_in { + set { + freeswitchPINVOKE.switch_device_stats_t_early_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_early_in_get(swigCPtr); + return ret; + } + } + + public uint early_out { + set { + freeswitchPINVOKE.switch_device_stats_t_early_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_early_out_get(swigCPtr); + return ret; + } + } + + public uint ring_wait { + set { + freeswitchPINVOKE.switch_device_stats_t_ring_wait_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_ring_wait_get(swigCPtr); + return ret; + } + } + public switch_device_stats_t() : this(freeswitchPINVOKE.new_switch_device_stats_t(), true) { } @@ -29842,6 +30891,8 @@ public enum switch_event_types_t { SWITCH_EVENT_RE_SCHEDULE, SWITCH_EVENT_RELOADXML, SWITCH_EVENT_NOTIFY, + SWITCH_EVENT_PHONE_FEATURE, + SWITCH_EVENT_PHONE_FEATURE_SUBSCRIBE, SWITCH_EVENT_SEND_MESSAGE, SWITCH_EVENT_RECV_MESSAGE, SWITCH_EVENT_REQUEST_PARAMS, @@ -29962,7 +31013,8 @@ namespace FreeSWITCH.Native { SWITCH_FILE_BUFFER_DONE = (1 << 14), SWITCH_FILE_WRITE_APPEND = (1 << 15), SWITCH_FILE_WRITE_OVER = (1 << 16), - SWITCH_FILE_NOMUX = (1 << 17) + SWITCH_FILE_NOMUX = (1 << 17), + SWITCH_FILE_BREAK_ON_CHANGE = (1 << 18) } } @@ -30071,12 +31123,12 @@ public class switch_file_handle : IDisposable { } } - public byte channels { + public uint channels { set { freeswitchPINVOKE.switch_file_handle_channels_set(swigCPtr, value); } get { - byte ret = freeswitchPINVOKE.switch_file_handle_channels_get(swigCPtr); + uint ret = freeswitchPINVOKE.switch_file_handle_channels_get(swigCPtr); return ret; } } @@ -30441,6 +31493,26 @@ public class switch_file_handle : IDisposable { } } + public uint cur_channels { + set { + freeswitchPINVOKE.switch_file_handle_cur_channels_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_file_handle_cur_channels_get(swigCPtr); + return ret; + } + } + + public uint cur_samplerate { + set { + freeswitchPINVOKE.switch_file_handle_cur_samplerate_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_file_handle_cur_samplerate_get(swigCPtr); + return ret; + } + } + public switch_file_handle() : this(freeswitchPINVOKE.new_switch_file_handle(), true) { } @@ -30899,6 +31971,17 @@ public class switch_frame : IDisposable { } } + public SWIGTYPE_p_payload_map_t pmap { + set { + freeswitchPINVOKE.switch_frame_pmap_set(swigCPtr, SWIGTYPE_p_payload_map_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_frame_pmap_get(swigCPtr); + SWIGTYPE_p_payload_map_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_payload_map_t(cPtr, false); + return ret; + } + } + public switch_frame() : this(freeswitchPINVOKE.new_switch_frame(), true) { } @@ -32618,6 +33701,150 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class switch_json_api_interface : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_json_api_interface(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_json_api_interface obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_json_api_interface() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if (swigCPtr.Handle != IntPtr.Zero) { + if (swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_json_api_interface(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + GC.SuppressFinalize(this); + } + } + + public string interface_name { + set { + freeswitchPINVOKE.switch_json_api_interface_interface_name_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_json_api_interface_interface_name_get(swigCPtr); + return ret; + } + } + + public string desc { + set { + freeswitchPINVOKE.switch_json_api_interface_desc_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_json_api_interface_desc_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t function { + set { + freeswitchPINVOKE.switch_json_api_interface_function_set(swigCPtr, SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_json_api_interface_function_get(swigCPtr); + SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_q_const__cJSON_p_switch_core_session_p_p_cJSON__switch_status_t(cPtr, false); + return ret; + } + } + + public string syntax { + set { + freeswitchPINVOKE.switch_json_api_interface_syntax_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_json_api_interface_syntax_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_switch_thread_rwlock_t rwlock { + set { + freeswitchPINVOKE.switch_json_api_interface_rwlock_set(swigCPtr, SWIGTYPE_p_switch_thread_rwlock_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_json_api_interface_rwlock_get(swigCPtr); + SWIGTYPE_p_switch_thread_rwlock_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_thread_rwlock_t(cPtr, false); + return ret; + } + } + + public int refs { + set { + freeswitchPINVOKE.switch_json_api_interface_refs_set(swigCPtr, value); + } + get { + int ret = freeswitchPINVOKE.switch_json_api_interface_refs_get(swigCPtr); + return ret; + } + } + + public SWIGTYPE_p_switch_mutex_t reflock { + set { + freeswitchPINVOKE.switch_json_api_interface_reflock_set(swigCPtr, SWIGTYPE_p_switch_mutex_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_json_api_interface_reflock_get(swigCPtr); + SWIGTYPE_p_switch_mutex_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_mutex_t(cPtr, false); + return ret; + } + } + + public switch_loadable_module_interface parent { + set { + freeswitchPINVOKE.switch_json_api_interface_parent_set(swigCPtr, switch_loadable_module_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_json_api_interface_parent_get(swigCPtr); + switch_loadable_module_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_loadable_module_interface(cPtr, false); + return ret; + } + } + + public switch_json_api_interface next { + set { + freeswitchPINVOKE.switch_json_api_interface_next_set(swigCPtr, switch_json_api_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_json_api_interface_next_get(swigCPtr); + switch_json_api_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_json_api_interface(cPtr, false); + return ret; + } + } + + public switch_json_api_interface() : this(freeswitchPINVOKE.new_switch_json_api_interface(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class switch_limit_interface : IDisposable { private HandleRef swigCPtr; protected bool swigCMemOwn; @@ -33016,6 +34243,17 @@ public class switch_loadable_module_interface : IDisposable { } } + public switch_json_api_interface json_api_interface { + set { + freeswitchPINVOKE.switch_loadable_module_interface_json_api_interface_set(swigCPtr, switch_json_api_interface.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_loadable_module_interface_json_api_interface_get(swigCPtr); + switch_json_api_interface ret = (cPtr == IntPtr.Zero) ? null : new switch_json_api_interface(cPtr, false); + return ret; + } + } + public switch_file_interface file_interface { set { freeswitchPINVOKE.switch_loadable_module_interface_file_interface_set(swigCPtr, switch_file_interface.getCPtr(value)); @@ -33581,7 +34819,8 @@ public enum switch_module_interface_name_t { SWITCH_ASR_INTERFACE, SWITCH_MANAGEMENT_INTERFACE, SWITCH_LIMIT_INTERFACE, - SWITCH_CHAT_APPLICATION_INTERFACE + SWITCH_CHAT_APPLICATION_INTERFACE, + SWITCH_JSON_API_INTERFACE } } @@ -33599,9 +34838,11 @@ namespace FreeSWITCH.Native { SOF_NONE = 0, SOF_NOBLOCK = (1 << 0), SOF_FORKED_DIAL = (1 << 1), - SOF_NO_EFFECTIVE_CID_NUM = (1 << 2), - SOF_NO_EFFECTIVE_CID_NAME = (1 << 3), - SOF_NO_LIMITS = (1 << 4) + SOF_NO_EFFECTIVE_ANI = (1 << 2), + SOF_NO_EFFECTIVE_ANIII = (1 << 3), + SOF_NO_EFFECTIVE_CID_NUM = (1 << 4), + SOF_NO_EFFECTIVE_CID_NAME = (1 << 5), + SOF_NO_LIMITS = (1 << 6) } } @@ -33649,6 +34890,22 @@ public enum switch_priority_t { namespace FreeSWITCH.Native { +public enum switch_pvt_class_t { + SWITCH_PVT_PRIMARY = 0, + SWITCH_PVT_SECONDARY +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_ring_ready_t { SWITCH_RING_READY_NONE, SWITCH_RING_READY_RINGING, @@ -33856,7 +35113,8 @@ public enum switch_rtp_bug_flag_t { RTP_BUG_ACCEPT_ANY_PACKETS = (1 << 7), RTP_BUG_GEN_ONE_GEN_ALL = (1 << 8), RTP_BUG_CHANGE_SSRC_ON_MARKER = (1 << 9), - RTP_BUG_FLUSH_JB_ON_DTMF = (1 << 10) + RTP_BUG_FLUSH_JB_ON_DTMF = (1 << 10), + RTP_BUG_ACCEPT_ANY_PAYLOAD = (1 << 11) } } @@ -34044,6 +35302,9 @@ public enum switch_rtp_flag_t { SWITCH_RTP_FLAG_VIDEO, SWITCH_RTP_FLAG_ENABLE_RTCP, SWITCH_RTP_FLAG_RTCP_MUX, + SWITCH_RTP_FLAG_KILL_JB, + SWITCH_RTP_FLAG_VIDEO_BREAK, + SWITCH_RTP_FLAG_PAUSE, SWITCH_RTP_FLAG_INVALID } @@ -34930,6 +36191,16 @@ public class switch_scheduler_task : IDisposable { } } + public uint repeat { + set { + freeswitchPINVOKE.switch_scheduler_task_repeat_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_scheduler_task_repeat_get(swigCPtr); + return ret; + } + } + public string group { set { freeswitchPINVOKE.switch_scheduler_task_group_set(swigCPtr, value); @@ -36056,7 +37327,9 @@ public enum switch_status_t { SWITCH_STATUS_FOUND, SWITCH_STATUS_CONTINUE, SWITCH_STATUS_TERM, - SWITCH_STATUS_NOT_INITALIZED + SWITCH_STATUS_NOT_INITALIZED, + SWITCH_STATUS_XBREAK = 35, + SWITCH_STATUS_WINBREAK = 730035 } } @@ -36505,6 +37778,17 @@ public class switch_thread_data_t : IDisposable { } } + public SWIGTYPE_p_apr_pool_t pool { + set { + freeswitchPINVOKE.switch_thread_data_t_pool_set(swigCPtr, SWIGTYPE_p_apr_pool_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_thread_data_t_pool_get(swigCPtr); + SWIGTYPE_p_apr_pool_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_apr_pool_t(cPtr, false); + return ret; + } + } + public switch_thread_data_t() : this(freeswitchPINVOKE.new_switch_thread_data_t(), true) { } @@ -37377,7 +38661,7 @@ namespace FreeSWITCH.Native { SWITCH_XML_SECTION_CONFIG = (1 << 0), SWITCH_XML_SECTION_DIRECTORY = (1 << 1), SWITCH_XML_SECTION_DIALPLAN = (1 << 2), - SWITCH_XML_SECTION_PHRASES = (1 << 3), + SWITCH_XML_SECTION_LANGUAGES = (1 << 3), SWITCH_XML_SECTION_CHATPLAN = (1 << 4), SWITCH_XML_SECTION_MAX = (1 << 4) } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 59eacde94c..bbef0b79bd 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -510,10 +510,10 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se } pmap->allocated = 1; - pmap->recv_pt = pt; + pmap->recv_pt = (switch_payload_t)pt; if (sdp_type == SDP_TYPE_REQUEST || !exists) { - pmap->pt = pt; + pmap->pt = (switch_payload_t)pt; } if (negotiated) { From 545d1e507967b1910e86c5a0c156bd0d7a71196f Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 1 Nov 2013 00:27:10 -0400 Subject: [PATCH 043/656] freetdm: Fix hangup supervision on inbound calls for Analog E&M --- libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index 8cf43bbdfd..fd9c36dadf 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -643,7 +643,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) case FTDM_CHANNEL_STATE_RING: { ftdm_sleep(interval); - if (ftdmchan->state == FTDM_CHANNEL_STATE_UP && cas_answer) { + if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) { cas_bits = 0; ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CAS_BITS, &cas_bits); if (!(state_counter % 5000)) { From 774784fbee1542050d6fe824390be30d0a971dd0 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 1 Nov 2013 01:16:49 -0400 Subject: [PATCH 044/656] mod_freetdm: Handle read errors gracefully when the device is dead already --- libs/freetdm/mod_freetdm/mod_freetdm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 3ac9bd0a36..227d5a698f 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -789,11 +789,16 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch len = tech_pvt->read_frame.buflen; if (ftdm_channel_read(tech_pvt->ftdmchan, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) { + if (switch_test_flag(tech_pvt, TFLAG_DEAD)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to read from dead channel %s device %d:%d\n", name, span_id, chan_id); + goto normal_failure; + } switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id); if (++tech_pvt->read_error > FTDM_MAX_READ_WRITE_ERRORS) { switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "too many I/O read errors on channel %s device %d:%d!\n", name, span_id, chan_id); goto fail; } + } else { tech_pvt->read_error = 0; } @@ -822,6 +827,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch fail: switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "clearing IO in channel %s device %d:%d!\n", name, span_id, chan_id); +normal_failure: switch_clear_flag_locked(tech_pvt, TFLAG_IO); return SWITCH_STATUS_GENERR; } From 3b0e8d9e2d4b876d38f445e369977d0d89a81c85 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 1 Nov 2013 02:07:10 -0400 Subject: [PATCH 045/656] freetdm: ftmod_zt: Refactor event processing to store OOB events that arrive during read/write operations --- libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c | 115 +++++++++++++++------ 1 file changed, 83 insertions(+), 32 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index bb7e477092..e7122740aa 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -951,6 +951,21 @@ static FIO_GET_ALARMS_FUNCTION(zt_get_alarms) return FTDM_SUCCESS; } +#define ftdm_zt_set_event_pending(fchan) \ + do { \ + ftdm_set_io_flag(fchan, FTDM_CHANNEL_IO_EVENT); \ + fchan->last_event_time = ftdm_current_time_in_ms(); \ + } while (0); + +#define ftdm_zt_store_chan_event(fchan, revent) \ + do { \ + if (fchan->io_data) { \ + ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Dropping event %d, not retrieved on time\n", revent); \ + } \ + fchan->io_data = (void *)zt_event_id; \ + ftdm_zt_set_event_pending(fchan); \ + } while (0); + /** * \brief Waits for an event on a Zaptel/DAHDI channel * \param ftdmchan Channel to open @@ -1015,7 +1030,7 @@ pollagain: *flags |= FTDM_WRITE; } - if (inflags & POLLPRI) { + if ((inflags & POLLPRI) || (ftdmchan->io_data && (*flags & FTDM_EVENTS))) { *flags |= FTDM_EVENTS; } @@ -1044,19 +1059,28 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) j++; } - r = poll(pfds, j, ms); + r = poll(pfds, j, ms); if (r == 0) { return FTDM_TIMEOUT; - } else if (r < 0 || (pfds[i-1].revents & POLLERR)) { + } else if (r < 0) { snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); return FTDM_FAIL; } for(i = 1; i <= span->chan_count; i++) { - if (pfds[i-1].revents & POLLPRI) { - ftdm_set_io_flag(span->channels[i], FTDM_CHANNEL_IO_EVENT); - span->channels[i]->last_event_time = ftdm_current_time_in_ms(); + + ftdm_channel_lock(span->channels[i]); + + if (pfds[i-1].revents & POLLERR) { + ftdm_log_chan(span->channels[i], FTDM_LOG_ERROR, "POLLERR, flags=%d\n", pfds[i-1].events); + + ftdm_channel_unlock(span->channels[i]); + + continue; + } + if ((pfds[i-1].revents & POLLPRI) || (span->channels[i]->io_data)) { + ftdm_zt_set_event_pending(span->channels[i]); k++; } if (pfds[i-1].revents & POLLIN) { @@ -1065,6 +1089,9 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) if (pfds[i-1].revents & POLLOUT) { ftdm_set_io_flag(span->channels[i], FTDM_CHANNEL_IO_WRITE); } + + ftdm_channel_unlock(span->channels[i]); + } if (!k) { @@ -1243,7 +1270,10 @@ FIO_CHANNEL_NEXT_EVENT_FUNCTION(zt_channel_next_event) ftdm_clear_io_flag(ftdmchan, FTDM_CHANNEL_IO_EVENT); } - if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { + if (ftdmchan->io_data) { + zt_event_id = (zt_event_t)ftdmchan->io_data; + ftdmchan->io_data = NULL; + } else if (ioctl(ftdmchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed retrieving event from channel: %s\n", strerror(errno)); return FTDM_FAIL; @@ -1274,30 +1304,48 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) uint32_t i, event_id = FTDM_OOB_INVALID; zt_event_t zt_event_id = 0; - for(i = 1; i <= span->chan_count; i++) { + for (i = 1; i <= span->chan_count; i++) { ftdm_channel_t *fchan = span->channels[i]; - if (ftdm_test_io_flag(fchan, FTDM_CHANNEL_IO_EVENT)) { - ftdm_clear_io_flag(fchan, FTDM_CHANNEL_IO_EVENT); - if (ioctl(fchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { - snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno)); - return FTDM_FAIL; - } - ftdm_channel_lock(fchan); - if ((zt_channel_process_event(fchan, &event_id, zt_event_id)) != FTDM_SUCCESS) { - ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to process DAHDI event %d from channel\n", zt_event_id); - ftdm_channel_unlock(fchan); - return FTDM_FAIL; - } + ftdm_channel_lock(fchan); + + if (!ftdm_test_io_flag(fchan, FTDM_CHANNEL_IO_EVENT)) { + ftdm_channel_unlock(fchan); - fchan->last_event_time = 0; - span->event_header.e_type = FTDM_EVENT_OOB; - span->event_header.enum_id = event_id; - span->event_header.channel = fchan; - *event = &span->event_header; - return FTDM_SUCCESS; + continue; } + + ftdm_clear_io_flag(fchan, FTDM_CHANNEL_IO_EVENT); + + if (fchan->io_data) { + zt_event_id = (zt_event_t)fchan->io_data; + fchan->io_data = NULL; + } else if (ioctl(fchan->sockfd, codes.GETEVENT, &zt_event_id) == -1) { + ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to retrieve DAHDI event from channel: %s\n", strerror(errno)); + + ftdm_channel_unlock(fchan); + + continue; + } + + if ((zt_channel_process_event(fchan, &event_id, zt_event_id)) != FTDM_SUCCESS) { + ftdm_log_chan(fchan, FTDM_LOG_ERROR, "Failed to process DAHDI event %d from channel\n", zt_event_id); + + ftdm_channel_unlock(fchan); + + return FTDM_FAIL; + } + + fchan->last_event_time = 0; + span->event_header.e_type = FTDM_EVENT_OOB; + span->event_header.enum_id = event_id; + span->event_header.channel = fchan; + *event = &span->event_header; + + ftdm_channel_unlock(fchan); + + return FTDM_SUCCESS; } return FTDM_FAIL; @@ -1348,11 +1396,13 @@ static FIO_READ_FUNCTION(zt_read) } if (handle_dtmf_event(ftdmchan, zt_event_id)) { - /* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */ - ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Event %d is not dmtf related. Skipping one media read cycle\n", zt_event_id); + /* Enqueue this event for later */ + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Deferring event %d to be able to read data\n", zt_event_id); + ftdm_zt_store_chan_event(ftdmchan, zt_event_id); + } else { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Skipping one IO read cycle due to DTMF event processing\n"); } - ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Skipping one IO read cycle due to events pending in the driver queue\n"); - break; + continue; } /* Read error, keep going unless to many errors force us to abort ...*/ @@ -1405,8 +1455,9 @@ tryagain: } if (handle_dtmf_event(ftdmchan, zt_event_id)) { - /* we should enqueue this event somewhere so it can be retrieved by the user, for now, dropping it to see what it is! */ - ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Dropping event %d to be able to write data\n", zt_event_id); + /* Enqueue this event for later */ + ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Deferring event %d to be able to write data\n", zt_event_id); + ftdm_zt_store_chan_event(ftdmchan, zt_event_id); } goto tryagain; From 7542c5877c718de4856167e508e2a181d458e059 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Sun, 3 Nov 2013 20:22:41 -0500 Subject: [PATCH 046/656] freetdm: E&M: Set the line offhook when suspended --- .../src/ftmod/ftmod_analog_em/ftmod_analog_em.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index fd9c36dadf..fdeb67f4b9 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -291,13 +291,23 @@ static FIO_CHANNEL_SET_SIG_STATUS_FUNCTION(analog_em_set_channel_sig_status) return FTDM_FAIL; case FTDM_SIG_STATE_SUSPENDED: if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { + int cas_bits = 0xFF; ftdm_set_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_CAS_BITS, &cas_bits); + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { + ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL); + } ftdm_analog_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED); } break; case FTDM_SIG_STATE_UP: if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED)) { + int cas_bits = 0x00; ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUSPENDED); + ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_CAS_BITS, &cas_bits); + if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) { + ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL); + } if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) { ftdm_analog_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP); } From fca7a4732c7e595d028c4b28ebac216e1596f5a3 Mon Sep 17 00:00:00 2001 From: wavecb Date: Thu, 7 Nov 2013 21:49:24 +0800 Subject: [PATCH 047/656] add miss strlcat strlcpy check for libedit --- libs/libedit/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libedit/configure.ac b/libs/libedit/configure.ac index 207bb0f118..7bd2ac6326 100644 --- a/libs/libedit/configure.ac +++ b/libs/libedit/configure.ac @@ -71,7 +71,7 @@ AC_PROG_GCC_TRADITIONAL #AC_FUNC_REALLOC AC_TYPE_SIGNAL AC_FUNC_STAT -AC_CHECK_FUNCS([endpwent isascii memchr memset re_comp regcomp strcasecmp strchr strcspn strdup strerror strrchr strstr strtol issetugid]) +AC_CHECK_FUNCS([endpwent isascii memchr memset re_comp regcomp strcasecmp strchr strlcat strlcpy strcspn strdup strerror strrchr strstr strtol issetugid]) EL_GETPW_R_POSIX EL_GETPW_R_DRAFT From 035818aa3aaf044790df1056c48d4a4b1da8e2f7 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Fri, 8 Nov 2013 09:38:10 -0500 Subject: [PATCH 048/656] mod_rayo: log when rayo call is rejected because there are no online clients --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index f852d2c5f8..7bb5dfc6f8 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -3218,6 +3218,7 @@ SWITCH_STANDARD_APP(rayo_app) /* nobody to offer to */ if (!ok) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Rejecting rayo call - there are no online rayo clients to offer call to\n"); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE); } } From a5328fe9c3582a8a97926c3e8b80b23887da7be0 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Fri, 8 Nov 2013 11:43:24 -0500 Subject: [PATCH 049/656] mod_rayo: send/receivefax bugfixes, also allow outbound calls not created with to be offered --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 26 +++++++------------ src/mod/event_handlers/mod_rayo/mod_rayo.h | 2 +- .../mod_rayo/rayo_fax_components.c | 14 +++++++--- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 7bb5dfc6f8..88eb44b417 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -983,18 +983,13 @@ int rayo_call_is_faxing(struct rayo_call *call) } /** - * Set faxing flag if faxing is not in progress + * Set faxing flag * @param call the call to flag * @param faxing true if faxing is in progress - * @return true if set, false if can't set because faxing is already in progress. Reset always succeeds. */ -int rayo_call_set_faxing(struct rayo_call *call, int faxing) +void rayo_call_set_faxing(struct rayo_call *call, int faxing) { - if (!faxing || (faxing && !call->faxing)) { - call->faxing = faxing; - return 1; - } - return 0; + call->faxing = faxing; } #define RAYO_MIXER_LOCATE(mixer_name) rayo_mixer_locate(mixer_name, __FILE__, __LINE__) @@ -3174,18 +3169,17 @@ SWITCH_STANDARD_APP(rayo_app) } } if (!call) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Missing rayo call!!\n"); - goto done; + /* this scenario can only happen if a call was originated through a mechanism other than + and then the rayo APP was executed to offer control */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Outbound call that wasn't created with , will try to offer control\n"); } ok = 1; - } else { - /* inbound call - offer control */ + } + + if (!call) { + /* offer control */ switch_hash_index_t *hi = NULL; iks *offer = NULL; - if (call) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Call is already under Rayo 3PCC!\n"); - goto done; - } call = rayo_call_create(switch_core_session_get_uuid(session)); switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_call_jid", RAYO_JID(call)); diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.h b/src/mod/event_handlers/mod_rayo/mod_rayo.h index c65236b64a..b862802f31 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.h +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.h @@ -155,7 +155,7 @@ extern void rayo_actor_destroy(struct rayo_actor *actor, const char *file, int l extern int rayo_call_is_joined(struct rayo_call *call); extern int rayo_call_is_faxing(struct rayo_call *call); -extern int rayo_call_set_faxing(struct rayo_call *call, int faxing); +extern void rayo_call_set_faxing(struct rayo_call *call, int faxing); extern const char *rayo_call_get_dcp_jid(struct rayo_call *call); #define rayo_mixer_get_name(mixer) RAYO_ID(mixer) diff --git a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c index 420853104a..bce34dc9d9 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c @@ -92,7 +92,7 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't send fax on a joined call"); } - if (!rayo_call_set_faxing(RAYO_CALL(call), 1)) { + if (rayo_call_is_faxing(RAYO_CALL(call))) { return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress"); } @@ -199,6 +199,8 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message /* clear fax interrupt variable */ switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); + rayo_call_set_faxing(RAYO_CALL(call), 1); + /* execute txfax APP */ if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); @@ -214,6 +216,7 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message if (execute_event) { switch_event_destroy(&execute_event); } + rayo_call_set_faxing(RAYO_CALL(call), 0); RAYO_UNLOCK(sendfax_component); } else { /* component starting... */ @@ -221,6 +224,7 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message } } else { response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create txfax event"); + rayo_call_set_faxing(RAYO_CALL(call), 0); RAYO_UNLOCK(sendfax_component); } @@ -255,7 +259,7 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "can't receive fax on a joined call"); } - if (!rayo_call_set_faxing(RAYO_CALL(call), 1)) { + if (rayo_call_is_faxing(RAYO_CALL(call))) { return iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, "fax already in progress"); } @@ -264,7 +268,7 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess receivefax_component = switch_core_alloc(pool, sizeof(*receivefax_component)); rayo_component_init((struct rayo_component *)receivefax_component, pool, RAT_CALL_COMPONENT, "receivefax", NULL, call, iks_find_attrib(iq, "from")); file_no = rayo_actor_seq_next(call); - receivefax_component->filename = switch_core_sprintf(pool, "%s%s%s-%d", + receivefax_component->filename = switch_core_sprintf(pool, "%s%s%s-%d.tif", globals.file_prefix, SWITCH_PATH_SEPARATOR, switch_core_session_get_uuid(session), file_no); if (!strncmp(receivefax_component->filename, "http://", 7) || !strncmp(receivefax_component->filename, "https://", 8)) { /* This is an HTTP URL, need to PUT after fax is received */ @@ -298,6 +302,8 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess /* clear fax interrupt variable */ switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); + rayo_call_set_faxing(RAYO_CALL(call), 1); + /* execute rxfax APP */ if (switch_event_create(&execute_event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); @@ -313,6 +319,7 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess if (execute_event) { switch_event_destroy(&execute_event); } + rayo_call_set_faxing(RAYO_CALL(call), 0); RAYO_UNLOCK(receivefax_component); } else { /* component starting... */ @@ -320,6 +327,7 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess } } else { response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "failed to create rxfax event"); + rayo_call_set_faxing(RAYO_CALL(call), 0); RAYO_UNLOCK(receivefax_component); } From 92f6986b406d01c646e3cdecec861cab9dd36b87 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Nov 2013 22:36:35 +0500 Subject: [PATCH 050/656] FS-5945 --resolve --- .../applications/mod_commands/mod_commands.c | 89 +++++++++++++++---- 1 file changed, 70 insertions(+), 19 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 2e4259817a..4a3153de5a 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1929,40 +1929,91 @@ SWITCH_STANDARD_API(cond_function) } a = argv[0]; + while(*a == ' ' || *a == '\t') a++; - if ((expr = strchr(a, '!'))) { - *expr++ = '\0'; - if (*expr == '=') { - o = O_NE; - } - } else if ((expr = strchr(a, '>'))) { - if (*(expr + 1) == '=') { + if (*a == '\'') { + if ((expr = switch_find_end_paren(a, '\'', '\''))) { + a++; *expr++ = '\0'; - o = O_GE; } else { - o = O_GT; + goto error; } - } else if ((expr = strchr(a, '<'))) { - if (*(expr + 1) == '=') { + } else { + if ((expr = strchr(a, ' '))) { *expr++ = '\0'; - o = O_LE; } else { - o = O_LT; - } - } else if ((expr = strchr(a, '='))) { - *expr++ = '\0'; - if (*expr == '=') { - o = O_EQ; + expr = a; } } + while(expr && *expr) { + switch(*expr) { + case '!': + case '<': + case '>': + case '=': + goto done; + default: + expr++; + break; + } + } + + done: + + switch(*expr) { + case '!': + *expr++ = '\0'; + if (*expr == '=') { + o = O_NE; + *expr++ = '\0'; + } + break; + + case '>': + *expr++ = '\0'; + if (*expr == '=') { + o = O_GE; + *expr++ = '\0'; + } else { + o = O_GT; + } + break; + + case '<': + *expr++ = '\0'; + if (*expr == '=') { + o = O_LE; + *expr++ = '\0'; + } else { + o = O_LT; + } + break; + + case '=': + *expr++ = '\0'; + if (*expr == '=') { + o = O_EQ; + *expr++ = '\0'; + } + break; + + default: + goto error; + } + + if (o) { char *s_a = NULL, *s_b = NULL; int a_is_num, b_is_num; - *expr++ = '\0'; + + expr++; b = expr; + s_a = switch_strip_spaces(a, SWITCH_TRUE); s_b = switch_strip_spaces(b, SWITCH_TRUE); + + a_is_num = switch_is_number(s_a); b_is_num = switch_is_number(s_b); From f4cdbea58064cb45ab84c93363d55d3e17a3a9a7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 8 Nov 2013 23:25:16 +0500 Subject: [PATCH 051/656] bump number --- src/mod/codecs/mod_vp8/mod_vp8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/codecs/mod_vp8/mod_vp8.c b/src/mod/codecs/mod_vp8/mod_vp8.c index 0fe64c72b8..2a0a5540ba 100644 --- a/src/mod/codecs/mod_vp8/mod_vp8.c +++ b/src/mod/codecs/mod_vp8/mod_vp8.c @@ -95,7 +95,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vp8_load) SWITCH_ADD_CODEC(codec_interface, "ulpfec Video (passthru)"); switch_core_codec_add_implementation(pool, codec_interface, - SWITCH_CODEC_TYPE_VIDEO, 103, "ulpfec", NULL, 90000, 90000, 0, + SWITCH_CODEC_TYPE_VIDEO, 104, "ulpfec", NULL, 90000, 90000, 0, 0, 0, 0, 0, 1, 1, switch_vp8_init, switch_vp8_encode, switch_vp8_decode, switch_vp8_destroy); /* indicate that the module should continue to be loaded */ From bf4440d0c30b336976a900ccd15950e1a9acf70c Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 5 Jul 2013 04:22:26 +0000 Subject: [PATCH 052/656] Handle APR / apr-util build settings properly After being configured, APR and apr-util provide config scripts that enumerate the libraries and compiler and linker options needed to build code relying on APR/apr-util. This patch causes us to more fully include the output of these scripts in our build process. FS-5574 --resolve --- Makefile.am | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 21b83bad2f..a3e942a036 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,9 +3,17 @@ SUBDIRS = . src AUTOMAKE_OPTIONS = foreign NAME = freeswitch +AM_LIBAPR_CFLAGS := $(shell ./libs/apr/apr-1-config --cflags) +AM_LIBAPR_CPPFLAGS := $(shell ./libs/apr/apr-1-config --cppflags --includes) +AM_LIBAPR_LDFLAGS := $(shell ./libs/apr/apr-1-config --ldflags) +AM_LIBAPR_LIBS := $(subst $(CURDIR)/,,$(shell ./libs/apr/apr-1-config \--link-libtool \--libs)) +AM_LIBAPU_CPPFLAGS := $(shell ./libs/apr-util/apu-1-config --includes) +AM_LIBAPU_LDFLAGS := $(shell ./libs/apr-util/apu-1-config --ldflags) +AM_LIBAPU_LIBS := $(subst $(CURDIR)/,,$(shell ./libs/apr-util/apu-1-config \--link-libtool \--libs)) + AM_CFLAGS = $(SWITCH_AM_CFLAGS) $(SWITCH_ANSI_CFLAGS) AM_CPPFLAGS = $(SWITCH_AM_CXXFLAGS) -Ilibs/sofia-sip/libsofia-sip-ua/sdp -Ilibs/sofia-sip/libsofia-sip-ua/su -AM_LDFLAGS = $(SWITCH_AM_LDFLAGS) +AM_LDFLAGS = $(SWITCH_AM_LDFLAGS) $(AM_LIBAPR_LDFLAGS) $(AM_LIBAPU_LDFLAGS) DEFAULT_SOUNDS=en-us-callie-8000 @@ -101,8 +109,8 @@ $(RECURSIVE_TARGETS): freeswitch exit 1; \ fi ; -CORE_CFLAGS = `$(switch_builddir)/libs/apr/apr-1-config --cflags --cppflags --includes` -CORE_CFLAGS += `$(switch_builddir)/libs/apr-util/apu-1-config --includes` +CORE_CFLAGS = $(AM_LIBAPR_CFLAGS) $(AM_LIBAPR_CPPFLAGS) +CORE_CFLAGS += $(AM_LIBAPU_CPPFLAGS) CORE_CFLAGS += -I$(switch_srcdir)/libs/libtpl-1.5/src CORE_CFLAGS += -I$(switch_srcdir)/libs/stfu CORE_CFLAGS += -I$(switch_builddir)/libs/sqlite @@ -112,7 +120,7 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include -Ilibs/srtp/crypto/include CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src -I$(switch_srcdir)/libs/tiff-4.0.2/libtiff -CORE_LIBS = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la +CORE_LIBS = $(AM_LIBAPU_LIBS) $(AM_LIBAPR_LIBS) CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la if ENABLE_SRTP From 04aac8c932ec853145e3efb60014d6f6e4fefafb Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 4 Nov 2013 20:30:58 +0000 Subject: [PATCH 053/656] Pull out our own libuuid detection APR is the only reason we depend on libuuid, so we'll rely on APR's tools here. This partially reverts commit f7fb54d0cd22c361298c772ce025a47f7937631d. --- acinclude.m4 | 1 - build/config/uuid.m4 | 17 ----------------- configure.in | 4 ---- 3 files changed, 22 deletions(-) delete mode 100644 build/config/uuid.m4 diff --git a/acinclude.m4 b/acinclude.m4 index 58b5500a80..aeba17b5c3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -6,7 +6,6 @@ m4_include([build/config/ac_gcc_archflag.m4]) m4_include([build/config/ac_gcc_x86_cpuid.m4]) m4_include([build/config/ax_lib_mysql.m4]) m4_include([build/config/ax_check_java.m4]) -m4_include([build/config/uuid.m4]) m4_include([build/config/erlang.m4]) m4_include([build/config/odbc.m4]) m4_include([build/config/sched_setaffinity.m4]) diff --git a/build/config/uuid.m4 b/build/config/uuid.m4 deleted file mode 100644 index 7f37c23c66..0000000000 --- a/build/config/uuid.m4 +++ /dev/null @@ -1,17 +0,0 @@ -AC_DEFUN([CHECK_LIBUUID], - [ - PKG_CHECK_MODULES([LIBUUID], [uuid >= 1.41.2], - [LIBUUID_FOUND=yes], [LIBUUID_FOUND=no]) - if test "$LIBUUID_FOUND" = "no" ; then - PKG_CHECK_MODULES([LIBUUID], [uuid], - [LIBUUID_FOUND=yes], [LIBUUID_FOUND=no]) - if test "$LIBUUID_FOUND" = "no" ; then - AC_MSG_WARN([libuuid development package highly recommended!]) - else - LIBUUID_INCLUDEDIR=$(pkg-config --variable=includedir uuid) - LIBUUID_CFLAGS+=" -I$LIBUUID_INCLUDEDIR/uuid " - fi - fi - AC_SUBST([LIBUUID_CFLAGS]) - AC_SUBST([LIBUUID_LIBS]) - ]) diff --git a/configure.in b/configure.in index 42256e2dda..83d9fa0d17 100644 --- a/configure.in +++ b/configure.in @@ -412,10 +412,6 @@ if test "x$enable_core_odbc_support" != "xno"; then AC_CHECK_LIB([odbc], [SQLDisconnect],, AC_MSG_ERROR([no usable libodbc; please install unixodbc devel package or equivalent])) fi -CHECK_LIBUUID -SWITCH_AM_LDFLAGS="$LIBUUID_LIBS $SWITCH_AM_LDFLAGS" -SWITCH_AM_CFLAGS="$LIBUUID_CFLAGS $SWITCH_AM_CFLAGS" - AC_ARG_ENABLE(core-pgsql-support, [AS_HELP_STRING([--enable-core-pgsql-support], [Compile with PGSQL Support])],,[enable_core_pgsql_support="no"]) AC_ARG_ENABLE(core-pgsql-pkgconfig, From b18e72162e123e64f79d6979214cd69d0e3292d2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 9 Nov 2013 00:59:16 +0500 Subject: [PATCH 054/656] uncomment --- src/mod/applications/mod_conference/mod_conference.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 2d7a9df244..55e681aa09 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -8422,8 +8422,8 @@ SWITCH_STANDARD_APP(conference_function) msg.from = __FILE__; /* Tell the channel we are going to be in a bridge */ - //msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; - //switch_core_session_receive_message(session, &msg); + msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; + switch_core_session_receive_message(session, &msg); /* Run the conference loop */ conference_loop_output(&member); From 8469e83835e16d49fdd16a96105fcce45cb114c5 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 8 Nov 2013 19:08:14 -0500 Subject: [PATCH 055/656] freetdm: ftmod_analog_em: Remove constant CAS debug log --- libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index fdeb67f4b9..8a537bb5e6 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -656,9 +656,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj) if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) { cas_bits = 0; ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CAS_BITS, &cas_bits); - if (!(state_counter % 5000)) { - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "CAS bits: 0x%X\n", cas_bits); - } if (cas_bits == 0x0) { cas_hangup += interval; if (cas_hangup >= cas_hangup_ms) { From 0af078b6a97107bca0bf7848583ed6d9a2230109 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 9 Nov 2013 01:06:39 +0000 Subject: [PATCH 056/656] Avoid building mod_java on sid for now We're getting dependency errors that seem to be an upstream issue. --- debian/bootstrap.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index b9776f14ac..03953b36c0 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -36,6 +36,7 @@ avoid_mods=( xml_int/mod_xml_radius ) avoid_mods_sid=( + languages/mod_java ) avoid_mods_jessie=( ) From a4dd6ccb42d8f54a38cef926f6f8eed0389c5bdd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 9 Nov 2013 23:02:11 +0500 Subject: [PATCH 057/656] fix some issues in passthrough of fec packets --- src/switch_core_media.c | 18 +++++++++++++++++- src/switch_rtp.c | 5 ++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index bbef0b79bd..61048d9ad2 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -495,6 +495,8 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se if (!exists) { + switch_ssize_t hlen = -1; + if (engine->payload_map && !engine->payload_map->allocated) { pmap = engine->payload_map; } else { @@ -507,6 +509,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se pmap->rm_encoding = pmap->iananame; pmap->ptime = ptime; pmap->rate = rate; + pmap->hash = switch_ci_hashfunc_default(pmap->iananame, &hlen); } pmap->allocated = 1; @@ -5643,6 +5646,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_media_handle_t *smh; ice_t *ice_out; int vp8 = 0; + int red = 0; payload_map_t *pmap; switch_assert(session); @@ -6216,6 +6220,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess vp8 = v_engine->cur_payload_map->pt; } + if (!strcasecmp(v_engine->cur_payload_map->rm_encoding, "red")) { + red = v_engine->cur_payload_map->pt; + } + rate = v_engine->cur_payload_map->rm_rate; switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n", v_engine->cur_payload_map->pt, v_engine->cur_payload_map->rm_encoding, @@ -6299,6 +6307,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess vp8 = ianacode; } + if (!strcasecmp(imp->iananame, "red")) { + red = ianacode; + } + if (channels > 1) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d/%d\n", ianacode, imp->iananame, imp->samples_per_second, channels); @@ -6377,11 +6389,15 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\n", bw); } - if (vp8) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-fb:%d ccm fir\n", vp8); } + + if (red) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), + "a=rtcp-fb:%d nack\n", vp8); + } switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u cname:%s\n", v_engine->ssrc, smh->cname); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u msid:%s v0\n", v_engine->ssrc, smh->msid); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index a0e80013f0..aa296c95da 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -399,7 +399,6 @@ struct switch_rtp { switch_core_session_t *session; payload_map_t **pmaps; payload_map_t *pmap_tail; - int pmap_ttl; #ifdef ENABLE_ZRTP zrtp_session_t *zrtp_session; @@ -6200,10 +6199,10 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra rtp_session->stats.outbound.packet_count++; } - if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps && rtp_session->pmap_ttl > 1) { + if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) { payload_map_t *pmap; - switch_mutex_lock(rtp_session->flag_mutex); + switch_mutex_lock(rtp_session->flag_mutex); for (pmap = *rtp_session->pmaps; pmap; pmap = pmap->next) { if (pmap->hash == frame->pmap->hash && !strcmp(pmap->iananame, frame->pmap->iananame)) { payload = pmap->recv_pt; From 6e9fa3ba277774a6240af8fcaa252928a7a693c9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 9 Nov 2013 23:14:20 +0500 Subject: [PATCH 058/656] revert 04aac8c932ec853145e3efb60014d6f6e4fefafb it causes recursion loop in some systems --- acinclude.m4 | 1 + configure.in | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index aeba17b5c3..58b5500a80 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -6,6 +6,7 @@ m4_include([build/config/ac_gcc_archflag.m4]) m4_include([build/config/ac_gcc_x86_cpuid.m4]) m4_include([build/config/ax_lib_mysql.m4]) m4_include([build/config/ax_check_java.m4]) +m4_include([build/config/uuid.m4]) m4_include([build/config/erlang.m4]) m4_include([build/config/odbc.m4]) m4_include([build/config/sched_setaffinity.m4]) diff --git a/configure.in b/configure.in index 83d9fa0d17..42256e2dda 100644 --- a/configure.in +++ b/configure.in @@ -412,6 +412,10 @@ if test "x$enable_core_odbc_support" != "xno"; then AC_CHECK_LIB([odbc], [SQLDisconnect],, AC_MSG_ERROR([no usable libodbc; please install unixodbc devel package or equivalent])) fi +CHECK_LIBUUID +SWITCH_AM_LDFLAGS="$LIBUUID_LIBS $SWITCH_AM_LDFLAGS" +SWITCH_AM_CFLAGS="$LIBUUID_CFLAGS $SWITCH_AM_CFLAGS" + AC_ARG_ENABLE(core-pgsql-support, [AS_HELP_STRING([--enable-core-pgsql-support], [Compile with PGSQL Support])],,[enable_core_pgsql_support="no"]) AC_ARG_ENABLE(core-pgsql-pkgconfig, From afaa8e3a751074a14f923a0e4d9c68617d6fdb9b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 10 Nov 2013 02:03:31 +0000 Subject: [PATCH 059/656] Add back build/config/uuid.m4 missed from reversion This finishes reverting commit 04aac8c932ec853145e3efb60014d6f6e4fefafb. --- build/config/uuid.m4 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 build/config/uuid.m4 diff --git a/build/config/uuid.m4 b/build/config/uuid.m4 new file mode 100644 index 0000000000..7f37c23c66 --- /dev/null +++ b/build/config/uuid.m4 @@ -0,0 +1,17 @@ +AC_DEFUN([CHECK_LIBUUID], + [ + PKG_CHECK_MODULES([LIBUUID], [uuid >= 1.41.2], + [LIBUUID_FOUND=yes], [LIBUUID_FOUND=no]) + if test "$LIBUUID_FOUND" = "no" ; then + PKG_CHECK_MODULES([LIBUUID], [uuid], + [LIBUUID_FOUND=yes], [LIBUUID_FOUND=no]) + if test "$LIBUUID_FOUND" = "no" ; then + AC_MSG_WARN([libuuid development package highly recommended!]) + else + LIBUUID_INCLUDEDIR=$(pkg-config --variable=includedir uuid) + LIBUUID_CFLAGS+=" -I$LIBUUID_INCLUDEDIR/uuid " + fi + fi + AC_SUBST([LIBUUID_CFLAGS]) + AC_SUBST([LIBUUID_LIBS]) + ]) From fb78273ab00802022758e01d6afa0428da7f9aaa Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 10 Nov 2013 07:53:11 +0500 Subject: [PATCH 060/656] inherit dynamic payloads from A leg where applicable --- src/include/switch_core_media.h | 7 +++ src/switch_core_media.c | 98 +++++++++++++++++++++++++++------ 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 5c083101a9..b9a0b67625 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -305,6 +305,13 @@ SWITCH_DECLARE(void) switch_core_media_deinit(void); SWITCH_DECLARE(void) switch_core_media_set_stats(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_wake_video_thread(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_clear_crypto(switch_core_session_t *session); + +SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core_session_t *session, + switch_media_type_t type, + const char *iananame, + switch_payload_t *ptP, + switch_payload_t *recv_ptP); + SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session, switch_media_type_t type, const char *name, diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 61048d9ad2..daa535981f 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -162,6 +162,7 @@ struct switch_media_handle_s { char *origin; switch_mutex_t *mutex; + switch_mutex_t *sdp_mutex; const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS]; int num_negotiated_codecs; @@ -459,6 +460,50 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_process_t38_passthru(switch_co } +SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core_session_t *session, + switch_media_type_t type, + const char *iananame, + switch_payload_t *ptP, + switch_payload_t *recv_ptP) +{ + payload_map_t *pmap; + switch_media_handle_t *smh; + switch_rtp_engine_t *engine; + switch_payload_t pt = 0, recv_pt = 0; + int found = 0; + + switch_assert(session); + + if (!(smh = session->media_handle)) { + return SWITCH_STATUS_FALSE; + } + + engine = &smh->engines[type]; + + switch_mutex_lock(smh->sdp_mutex); + for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { + if (!strcasecmp(pmap->iananame, iananame)) { + pt = pmap->pt; + recv_pt = pmap->recv_pt; + found++; + } + } + switch_mutex_lock(smh->sdp_mutex); + + if (found) { + if (ptP) { + *ptP = pt; + } + if (recv_ptP) { + *recv_ptP = recv_pt; + } + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; + +} + SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session, switch_media_type_t type, @@ -482,7 +527,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se engine = &smh->engines[type]; - switch_mutex_lock(smh->mutex); + switch_mutex_lock(smh->sdp_mutex); for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { @@ -534,7 +579,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se } } - switch_mutex_unlock(smh->mutex); + switch_mutex_unlock(smh->sdp_mutex); return pmap; } @@ -1144,6 +1189,7 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t switch_mutex_init(&session->media_handle->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); + switch_mutex_init(&session->media_handle->sdp_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc = (uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (uint32_t) time(NULL)); @@ -1638,7 +1684,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session /* search for payload type */ - switch_mutex_lock(smh->mutex); + switch_mutex_lock(smh->sdp_mutex); for (pmap = engine->cur_payload_map; pmap; pmap = pmap->next) { if (engine->read_frame.payload == pmap->recv_pt) { engine->cur_payload_map = pmap; @@ -1652,7 +1698,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session break; } } - switch_mutex_unlock(smh->mutex); + switch_mutex_unlock(smh->sdp_mutex); if (!engine->reset_codec) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, @@ -5609,10 +5655,10 @@ SWITCH_DECLARE(void)switch_core_media_set_local_sdp(switch_core_session_t *sessi return; } - if (smh->mutex) switch_mutex_lock(smh->mutex); + if (smh->sdp_mutex) switch_mutex_lock(smh->sdp_mutex); smh->mparams->local_sdp_str = dup ? switch_core_session_strdup(session, sdp_str) : (char *) sdp_str; switch_channel_set_variable(session->channel, "rtp_local_sdp_str", smh->mparams->local_sdp_str); - if (smh->mutex) switch_mutex_unlock(smh->mutex); + if (smh->sdp_mutex) switch_mutex_unlock(smh->sdp_mutex); } @@ -5705,16 +5751,24 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess smh->mparams->cng_pt = 0; } + + if (!smh->payload_space) { int i; + smh->payload_space = 98; if (sdp_type == SDP_TYPE_REQUEST) { + switch_core_session_t *orig_session = NULL; + + switch_core_session_get_partner(session, &orig_session); + for (i = 0; i < smh->mparams->num_codecs; i++) { const switch_codec_implementation_t *imp = smh->codecs[i]; - + switch_payload_t orig_pt = 0; + smh->ianacodes[i] = imp->ianacode; if (smh->ianacodes[i] > 64) { @@ -5725,7 +5779,15 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess smh->mparams->cng_pt && use_cng && smh->mparams->cng_pt == smh->payload_space) { smh->payload_space++; } - smh->ianacodes[i] = (switch_payload_t)smh->payload_space++; + + if (orig_session && + switch_core_session_get_payload_code(orig_session, + imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, + imp->iananame, NULL, &orig_pt) == SWITCH_STATUS_SUCCESS) { + smh->ianacodes[i] = orig_pt; + } else { + smh->ianacodes[i] = (switch_payload_t)smh->payload_space++; + } } @@ -5739,6 +5801,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess SWITCH_FALSE); } + + if (orig_session) { + switch_core_session_rwunlock(orig_session); + } } } @@ -5850,13 +5916,13 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) { - switch_mutex_lock(smh->mutex); + switch_mutex_lock(smh->sdp_mutex); for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { if (pmap->pt != a_engine->cur_payload_map->pt) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt); } } - switch_mutex_unlock(smh->mutex); + switch_mutex_unlock(smh->sdp_mutex); } if ((smh->mparams->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || @@ -5890,7 +5956,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_AUDIO)) { - switch_mutex_lock(smh->mutex); + switch_mutex_lock(smh->sdp_mutex); for (pmap = a_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { if (pmap->pt != a_engine->cur_payload_map->pt) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n", @@ -5898,7 +5964,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess pmap->rate); } } - switch_mutex_unlock(smh->mutex); + switch_mutex_unlock(smh->sdp_mutex); } @@ -6169,13 +6235,13 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", v_engine->cur_payload_map->agreed_pt); if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) { - switch_mutex_lock(smh->mutex); + switch_mutex_lock(smh->sdp_mutex); for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { if (pmap->pt != v_engine->cur_payload_map->pt) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", pmap->pt); } } - switch_mutex_unlock(smh->mutex); + switch_mutex_unlock(smh->sdp_mutex); } } else if (smh->mparams->num_codecs) { @@ -6255,7 +6321,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (switch_media_handle_test_media_flag(smh, SCMF_MULTI_ANSWER_VIDEO)) { - switch_mutex_lock(smh->mutex); + switch_mutex_lock(smh->sdp_mutex); for (pmap = v_engine->cur_payload_map; pmap && pmap->allocated; pmap = pmap->next) { if (pmap->pt != v_engine->cur_payload_map->pt) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\n", @@ -6263,7 +6329,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } } - switch_mutex_unlock(smh->mutex); + switch_mutex_unlock(smh->sdp_mutex); } From 13dcbae0b43cb218ea4d4e0e295bfc45dffea73a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 10 Nov 2013 22:11:37 +0500 Subject: [PATCH 061/656] regression from last commit --- src/switch_core_media.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index daa535981f..758b2816a4 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -488,7 +488,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core found++; } } - switch_mutex_lock(smh->sdp_mutex); + switch_mutex_unlock(smh->sdp_mutex); if (found) { if (ptP) { @@ -5783,7 +5783,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (orig_session && switch_core_session_get_payload_code(orig_session, imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, - imp->iananame, NULL, &orig_pt) == SWITCH_STATUS_SUCCESS) { + imp->iananame, &orig_pt, NULL) == SWITCH_STATUS_SUCCESS) { smh->ianacodes[i] = orig_pt; } else { smh->ianacodes[i] = (switch_payload_t)smh->payload_space++; From 9500e120a9cb6ba37349399a4288c5d23a167815 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 11 Nov 2013 11:42:53 -0500 Subject: [PATCH 062/656] mod_rayo: fix config to passthrough loopback dialstrings --- conf/rayo/autoload_configs/rayo.conf.xml | 11 ++++++----- .../mod_rayo/conf/autoload_configs/rayo.conf.xml | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index c8171569af..82adf96faa 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -17,10 +17,10 @@ - + - - + + @@ -49,8 +49,9 @@ - - + + + diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index 3fdc772daf..dc90b519df 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -49,8 +49,9 @@ - - + + + From 0d1b647197e8e0f919a0dcf5847cee60e891789b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Nov 2013 00:11:23 +0500 Subject: [PATCH 063/656] remainder of previous patch to pass through dynamic payload numbers used --- src/include/switch_core_media.h | 2 +- src/mod/endpoints/mod_sofia/sofia.c | 25 +++++++++++--- src/switch_core_media.c | 51 ++++++++++++++++++++++------- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index b9a0b67625..cfbe9921eb 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -292,7 +292,7 @@ SWITCH_DECLARE(stfu_instance_t *) switch_core_media_get_jb(switch_core_session_t SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_get_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool); -SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp); +SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t sdp_type); SWITCH_DECLARE(void) switch_core_media_reset_autofix(switch_core_session_t *session, switch_media_type_t type); SWITCH_DECLARE(void) switch_core_media_check_outgoing_proxy(switch_core_session_t *session, switch_core_session_t *o_session); SWITCH_DECLARE(switch_status_t) switch_core_media_codec_chosen(switch_core_session_t *session, switch_media_type_t media); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 527de9b8fb..cd566c22bd 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5118,8 +5118,12 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status } tech_pvt->mparams.last_sdp_str = NULL; - if (!sofia_use_soa(tech_pvt) && sip->sip_payload && sip->sip_payload->pl_data) { - tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); + if (sip->sip_payload && sip->sip_payload->pl_data) { + switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE); + + if (!sofia_use_soa(tech_pvt)) { + tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); + } } @@ -5867,9 +5871,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Remote SDP:\n%s\n", r_sdp); tech_pvt->mparams.remote_sdp_str = switch_core_session_strdup(session, r_sdp); - if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { - switch_core_media_set_sdp_codec_string(session, r_sdp); - } + //if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { + // switch_core_media_set_sdp_codec_string(session, r_sdp, status < 200 ? SDP_TYPE_REQUEST : SDP_TYPE_RESPONSE); + //} sofia_glue_pass_sdp(tech_pvt, (char *) r_sdp); sofia_set_flag(tech_pvt, TFLAG_NEW_SDP); @@ -7882,8 +7886,13 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia const char *from_tag = ""; char *sql = NULL; char *acl_context = NULL; + const char *r_sdp = NULL; + profile->ib_calls++; + if (sip->sip_payload && sip->sip_payload->pl_data) { + r_sdp = sip->sip_payload->pl_data; + } if (!session || (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING))) { nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END()); @@ -7910,6 +7919,12 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia is_nat = "websockets"; } + + if (r_sdp) { + switch_core_media_set_sdp_codec_string(session, r_sdp, SDP_TYPE_REQUEST); + } + + if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) { if (sip && sip->sip_via) { const char *port = sip->sip_via->v_port; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 758b2816a4..e55cb537a1 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -40,9 +40,9 @@ #include #include -SWITCH_DECLARE(switch_t38_options_t *) switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m); -SWITCH_DECLARE(void) switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp); -SWITCH_DECLARE(void) switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp); +static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m); +static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp); +static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp, switch_sdp_type_t sdp_type); //#define GOOGLE_ICE #define RTCP_MUX @@ -263,7 +263,7 @@ SWITCH_DECLARE(const char *) switch_core_media_get_zrtp_hash(switch_core_session } -SWITCH_DECLARE(void) switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp) +static void switch_core_media_find_zrtp_hash(switch_core_session_t *session, sdp_session_t *sdp) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_rtp_engine_t *audio_engine; @@ -307,7 +307,7 @@ SWITCH_DECLARE(void) switch_core_media_find_zrtp_hash(switch_core_session_t *ses } -SWITCH_DECLARE(switch_t38_options_t *) switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m) +static switch_t38_options_t * switch_core_media_process_udptl(switch_core_session_t *session, sdp_session_t *sdp, sdp_media_t *m) { switch_t38_options_t *t38_options = switch_channel_get_private(session->channel, "t38_options"); sdp_attribute_t *attr; @@ -481,7 +481,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core engine = &smh->engines[type]; switch_mutex_lock(smh->sdp_mutex); - for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { + for (pmap = engine->payload_map; pmap ; pmap = pmap->next) { + + if (!pmap->allocated) continue; + if (!strcasecmp(pmap->iananame, iananame)) { pt = pmap->pt; recv_pt = pmap->recv_pt; @@ -548,15 +551,22 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se pmap = switch_core_alloc(session->pool, sizeof(*pmap)); } - pmap->sdp_type = sdp_type; pmap->type = type; pmap->iananame = switch_core_strdup(session->pool, name); pmap->rm_encoding = pmap->iananame; - pmap->ptime = ptime; - pmap->rate = rate; pmap->hash = switch_ci_hashfunc_default(pmap->iananame, &hlen); } + pmap->sdp_type = sdp_type; + + if (ptime) { + pmap->ptime = ptime; + } + + if (rate) { + pmap->rate = rate; + } + pmap->allocated = 1; pmap->recv_pt = (switch_payload_t)pt; @@ -7701,7 +7711,7 @@ SWITCH_DECLARE(stfu_instance_t *) switch_core_media_get_jb(switch_core_session_t //? -SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp) +SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_t *session, const char *r_sdp, switch_sdp_type_t sdp_type) { sdp_parser_t *parser; sdp_session_t *sdp; @@ -7717,7 +7727,7 @@ SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_ if ((parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { if ((sdp = sdp_session(parser))) { - switch_core_media_set_r_sdp_codec_string(session, switch_core_media_get_codec_string(session), sdp); + switch_core_media_set_r_sdp_codec_string(session, switch_core_media_get_codec_string(session), sdp, sdp_type); } sdp_parser_free(parser); @@ -7781,7 +7791,7 @@ static void add_audio_codec(sdp_rtpmap_t *map, int ptime, char *buf, switch_size } -SWITCH_DECLARE(void) switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp) +static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *session, const char *codec_string, sdp_session_t *sdp, switch_sdp_type_t sdp_type) { char buf[1024] = { 0 }; sdp_media_t *m; @@ -7839,8 +7849,25 @@ SWITCH_DECLARE(void) switch_core_media_set_r_sdp_codec_string(switch_core_sessio switch_core_media_find_zrtp_hash(session, sdp); switch_core_media_pass_zrtp_hash(session); + for (m = sdp->sdp_media; m; m = m->m_next) { + if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) { + for (map = m->m_rtpmaps; map; map = map->rm_next) { + + switch_core_media_add_payload_map(session, + m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, + map->rm_encoding, + sdp_type, + map->rm_pt, + 0, + 0, + SWITCH_FALSE); + } + } + } + for (m = sdp->sdp_media; m; m = m->m_next) { ptime = dptime; + if (m->m_type == sdp_media_image && m->m_port) { switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",t38"); } else if (m->m_type == sdp_media_audio && m->m_port) { From 5456daa010ab871e0d2d0ce600f4e8a672db1826 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 11 Nov 2013 16:47:07 -0600 Subject: [PATCH 064/656] add logical-direction to events --- src/switch_caller.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_caller.c b/src/switch_caller.c index fdd41a4dd7..f7a9e5d40a 100644 --- a/src/switch_caller.c +++ b/src/switch_caller.c @@ -313,6 +313,10 @@ SWITCH_DECLARE(void) switch_caller_profile_event_set_data(switch_caller_profile_ switch_snprintf(header_name, sizeof(header_name), "%s-Direction", prefix); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header_name, caller_profile->direction == SWITCH_CALL_DIRECTION_INBOUND ? "inbound" : "outbound"); + + switch_snprintf(header_name, sizeof(header_name), "%s-Logical-Direction", prefix); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header_name, caller_profile->logical_direction == SWITCH_CALL_DIRECTION_INBOUND ? + "inbound" : "outbound"); if (!zstr(caller_profile->username)) { switch_snprintf(header_name, sizeof(header_name), "%s-Username", prefix); From 681ea6c40bb78f8ac729a08a32ee9e834e69b100 Mon Sep 17 00:00:00 2001 From: wavecb Date: Tue, 12 Nov 2013 13:42:56 +0800 Subject: [PATCH 065/656] fix build on mac os 10.9 --- libs/curl/lib/strequal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/curl/lib/strequal.h b/libs/curl/lib/strequal.h index 6ec88d82d7..ce83d48aef 100644 --- a/libs/curl/lib/strequal.h +++ b/libs/curl/lib/strequal.h @@ -38,6 +38,6 @@ char *Curl_strcasestr(const char *haystack, const char *needle); #ifndef HAVE_STRLCAT #define strlcat(x,y,z) Curl_strlcat(x,y,z) #endif -size_t strlcat(char *dst, const char *src, size_t siz); +//size_t strlcat(char *dst, const char *src, size_t siz); #endif From 048a0eb89879f4e7e3a911a95cf07b5b1ef3854a Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 12 Nov 2013 11:02:37 -0500 Subject: [PATCH 066/656] FS-5961 --resolve mod_rayo: fixed , wasn't returning errors in some scenarios --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 118 +++++++++++++++------ 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 88eb44b417..7dcd6738dc 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -135,11 +135,13 @@ struct rayo_call { /** ID of joined party TODO this will be many mixers / calls */ const char *joined_id; /** set if response needs to be sent to IQ request */ - const char *dial_id; + const char *dial_request_id; /** channel destroy event */ switch_event_t *end_event; /** True if ringing event sent to client */ int ringing_sent; + /** True if request to create this call failed */ + int dial_request_failed; }; /** @@ -877,9 +879,9 @@ static void rayo_call_cleanup(struct rayo_actor *actor) iks *revent; iks *end; - if (!event) { + if (!event || call->dial_request_failed) { /* destroyed before FS session was created (in originate, for example) */ - return; + goto done; } revent = iks_new_presence("end", RAYO_NS, @@ -941,6 +943,10 @@ static void rayo_call_cleanup(struct rayo_actor *actor) RAYO_SEND_MESSAGE_DUP(actor, rayo_call_get_dcp_jid(call), revent); } + iks_delete(revent); + +done: + /* lost the race: pending join failed... send IQ result to client now. */ if (call->pending_join_request) { iks *request = call->pending_join_request; @@ -950,8 +956,9 @@ static void rayo_call_cleanup(struct rayo_actor *actor) iks_delete(call->pending_join_request); } - iks_delete(revent); - switch_event_destroy(&event); + if (event) { + switch_event_destroy(&event); + } switch_core_hash_destroy(&call->pcps); } @@ -1102,6 +1109,9 @@ static struct rayo_call *rayo_call_init(struct rayo_call *call, switch_memory_po call->joined_id = NULL; call->ringing_sent = 0; call->pending_join_request = NULL; + call->dial_request_id = NULL; + call->end_event = NULL; + call->dial_request_failed = 0; switch_core_hash_init(&call->pcps, pool); switch_safe_free(call_jid); @@ -2141,7 +2151,7 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void * /* create call and link to DCP */ call = rayo_call_create(NULL); call->dcp_jid = switch_core_strdup(RAYO_POOL(call), dcp_jid); - call->dial_id = iks_find_attrib(iq, "id"); + call->dial_request_id = iks_find_attrib(iq, "id"); switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_INFO, "%s has control of call\n", dcp_jid); uuid = switch_core_strdup(dtdata->pool, rayo_call_get_uuid(call)); @@ -2245,27 +2255,63 @@ static void *SWITCH_THREAD_FUNC rayo_dial_thread(switch_thread_t *thread, void * if (switch_api_execute("originate", stream.data, NULL, &api_stream) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got originate result: %s\n", (char *)api_stream.data); + switch_mutex_lock(RAYO_ACTOR(call)->mutex); /* check for failure */ if (strncmp("+OK", api_stream.data, strlen("+OK"))) { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_INFO, "Failed to originate call\n"); - if (call->dial_id) { + if (call->dial_request_id) { + call->dial_request_failed = 1; + call->dial_request_id = NULL; + /* map failure reason to iq error */ if (!strncmp("-ERR DESTINATION_OUT_OF_ORDER", api_stream.data, strlen("-ERR DESTINATION_OUT_OF_ORDER"))) { - /* this -ERR is received when out of sessions */ - response = iks_new_error(iq, STANZA_ERROR_RESOURCE_CONSTRAINT); + /* out of sessions, typically */ + response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data); + } else if (!strncmp("-ERR USER_NOT_REGISTERED", api_stream.data, strlen("-ERR USER_NOT_REGISTERED"))) { + response = iks_new_error_detailed(iq, STANZA_ERROR_UNEXPECTED_REQUEST, (char *)api_stream.data); + } else if (!strncmp("-ERR EXCHANGE_ROUTING_ERROR", api_stream.data, strlen("-ERR EXCHANGE_ROUTING_ERROR"))) { + /* max forwards */ + response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data); + } else if (!strncmp("-ERR CHAN_NOT_IMPLEMENTED", api_stream.data, strlen("-ERR CHAN_NOT_IMPLEMENTED"))) { + /* unsupported endpoint type */ + response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data); + } else if (!strncmp("-ERR INVALID_URL", api_stream.data, strlen("-ERR INVALID_URL"))) { + response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data); + } else if (!strncmp("-ERR INVALID_GATEWAY", api_stream.data, strlen("-ERR INVALID_GATEWAY"))) { + response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data); + } else if (!strncmp("-ERR INVALID_PROFILE", api_stream.data, strlen("-ERR INVALID_PROFILE"))) { + response = iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, (char *)api_stream.data); + } else if (!strncmp("-ERR SYSTEM_SHUTDOWN", api_stream.data, strlen("-ERR SYSTEM_SHUTDOWN"))) { + response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data); + } else if (!strncmp("-ERR GATEWAY_DOWN", api_stream.data, strlen("-ERR GATEWAY_DOWN"))) { + response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data); + } else if (!strncmp("-ERR INVALID_NUMBER_FORMAT", api_stream.data, strlen("-ERR INVALID_NUMBER_FORMAT"))) { + response = iks_new_error_detailed(iq, STANZA_ERROR_RESOURCE_CONSTRAINT, (char *)api_stream.data); + } else { + /* other unspecified error */ + response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, (char *)api_stream.data); } } } - } else if (call->dial_id) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to exec originate API\n"); - response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to execute originate API"); + switch_mutex_unlock(RAYO_ACTOR(call)->mutex); + } else { + switch_mutex_lock(RAYO_ACTOR(call)->mutex); + if (call->dial_request_id) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to exec originate API\n"); + call->dial_request_failed = 1; + call->dial_request_id = NULL; + response = iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "Failed to execute originate API"); + } + switch_mutex_unlock(RAYO_ACTOR(call)->mutex); } switch_safe_free(api_stream.data); } else { /* will only happen if misconfigured */ switch_log_printf(SWITCH_CHANNEL_UUID_LOG(rayo_call_get_uuid(call)), SWITCH_LOG_CRIT, "No dial gateway found for %s!\n", dial_to); + call->dial_request_failed = 1; + call->dial_request_id = NULL; response = iks_new_error_detailed_printf(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, "No dial gateway found for %s!\n", dial_to); goto done; } @@ -2719,21 +2765,27 @@ static void on_call_originate_event(struct rayo_client *rclient, switch_event_t if (call && (session = switch_core_session_locate(uuid))) { iks *response, *ref; - switch_channel_set_private(switch_core_session_get_channel(session), "rayo_call_private", call); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Got originate event\n"); + + switch_mutex_lock(RAYO_ACTOR(call)->mutex); + if (call->dial_request_id) { + switch_channel_set_private(switch_core_session_get_channel(session), "rayo_call_private", call); + + /* send response to DCP */ + response = iks_new("iq"); + iks_insert_attrib(response, "from", RAYO_JID(globals.server)); + iks_insert_attrib(response, "to", rayo_call_get_dcp_jid(call)); + iks_insert_attrib(response, "id", call->dial_request_id); + iks_insert_attrib(response, "type", "result"); + ref = iks_insert(response, "ref"); + iks_insert_attrib(ref, "xmlns", RAYO_NS); + + iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call)); + RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), response); + call->dial_request_id = NULL; + } + switch_mutex_unlock(RAYO_ACTOR(call)->mutex); switch_core_session_rwunlock(session); - - /* send response to DCP */ - response = iks_new("iq"); - iks_insert_attrib(response, "from", RAYO_JID(globals.server)); - iks_insert_attrib(response, "to", rayo_call_get_dcp_jid(call)); - iks_insert_attrib(response, "id", call->dial_id); - iks_insert_attrib(response, "type", "result"); - ref = iks_insert(response, "ref"); - iks_insert_attrib(ref, "xmlns", RAYO_NS); - - iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(call)); - RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), response); - call->dial_id = NULL; } RAYO_UNLOCK(call); } @@ -2754,9 +2806,15 @@ static void on_call_end_event(switch_event_t *event) switch_safe_free(event_str); } #endif - switch_event_dup(&call->end_event, event); - RAYO_UNLOCK(call); /* decrement ref from creation */ - RAYO_DESTROY(call); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_ID(call)), SWITCH_LOG_DEBUG, "Got channel destroy event\n"); + + switch_mutex_lock(RAYO_ACTOR(call)->mutex); + if (!call->dial_request_id && !call->dial_request_failed) { + switch_event_dup(&call->end_event, event); + RAYO_DESTROY(call); + RAYO_UNLOCK(call); /* decrement ref from creation */ + } + switch_mutex_unlock(RAYO_ACTOR(call)->mutex); RAYO_UNLOCK(call); /* decrement this ref */ } } @@ -2796,9 +2854,9 @@ static void on_call_ringing_event(struct rayo_client *rclient, switch_event_t *e switch_event_get_header(event, "variable_rayo_dcp_jid")); call->ringing_sent = 1; RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); - RAYO_UNLOCK(call); } switch_mutex_unlock(RAYO_ACTOR(call)->mutex); + RAYO_UNLOCK(call); } } } From 1fc018f5f229fe898ba5f1fea00f67909d40a681 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Nov 2013 10:22:58 -0600 Subject: [PATCH 067/656] FS-5211 --resolve --- src/mod/applications/mod_conference/mod_conference.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 55e681aa09..dd3d6bb4bb 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -6179,7 +6179,7 @@ static switch_status_t conf_api_sub_file_seek(conference_obj_t *conference, swit step = 1000; } - samps = step * (conference->rate / 1000); + samps = step * (conference->fnode->fh.native_rate / 1000); target = (int32_t)conference->fnode->fh.pos + samps; if (target < 0) { @@ -6190,7 +6190,7 @@ static switch_status_t conf_api_sub_file_seek(conference_obj_t *conference, swit switch_core_file_seek(&conference->fnode->fh, &pos, target, SEEK_SET); } else { - samps = switch_atoui(argv[2]) * (conference->rate / 1000); + samps = switch_atoui(argv[2]) * (conference->fnode->fh.native_rate / 1000); stream->write_function(stream, "+OK seek to position %d\n", samps); switch_core_file_seek(&conference->fnode->fh, &pos, samps, SEEK_SET); } From 043376b2db59e1a00e695469db29c2c440b1353d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Nov 2013 22:17:53 +0500 Subject: [PATCH 068/656] tweak --- src/switch_core_media.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index e55cb537a1..eee0affc86 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -534,7 +534,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { - exists = (!strcasecmp(name, pmap->iananame) && rate == pmap->rate && pmap->ptime == ptime); + exists = (!strcasecmp(name, pmap->iananame) && (!pmap->rate || rate == pmap->rate) && (pmap->ptime || pmap->ptime == ptime)); if (exists) { break; @@ -7850,16 +7850,26 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess switch_core_media_pass_zrtp_hash(session); for (m = sdp->sdp_media; m; m = m->m_next) { + ptime = dptime; + if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) { for (map = m->m_rtpmaps; map; map = map->rm_next) { - + for (attr = m->m_attributes; attr; attr = attr->a_next) { + if (zstr(attr->a_name)) { + continue; + } + if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { + ptime = atoi(attr->a_value); + break; + } + } switch_core_media_add_payload_map(session, m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, map->rm_encoding, sdp_type, map->rm_pt, - 0, - 0, + map->rm_rate, + ptime, SWITCH_FALSE); } } From 931d3fb86ae29f039d179c0cc0aa11b42ddc7326 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 12 Nov 2013 12:33:28 -0600 Subject: [PATCH 069/656] remove condition for mem leak --- libs/esl/src/esl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index d186665413..ede0675df0 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -1513,6 +1513,10 @@ ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char * } recv: + + esl_event_safe_destroy(&handle->last_sr_event); + + *handle->last_sr_reply = '\0'; status = esl_recv_event_timed(handle, ms, 0, &handle->last_sr_event); From 2771498707c194c70cf25ad9473be66ef59cfb46 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 13 Nov 2013 07:55:00 +0500 Subject: [PATCH 070/656] change to lua 5.2 --- src/mod/languages/mod_lua/freeswitch_lua.cpp | 22 +- src/mod/languages/mod_lua/hack.diff | 46 +- src/mod/languages/mod_lua/lua/Makefile | 163 +- src/mod/languages/mod_lua/lua/lapi.c | 899 ++++++---- src/mod/languages/mod_lua/lua/lapi.h | 14 +- src/mod/languages/mod_lua/lua/lauxlib.c | 1097 +++++++----- src/mod/languages/mod_lua/lua/lauxlib.h | 128 +- src/mod/languages/mod_lua/lua/lbaselib.c | 567 ++---- src/mod/languages/mod_lua/lua/lcode.c | 400 +++-- src/mod/languages/mod_lua/lua/lcode.h | 21 +- src/mod/languages/mod_lua/lua/ldblib.c | 219 +-- src/mod/languages/mod_lua/lua/ldebug.c | 624 +++---- src/mod/languages/mod_lua/lua/ldebug.h | 27 +- src/mod/languages/mod_lua/lua/ldo.c | 673 ++++--- src/mod/languages/mod_lua/lua/ldo.h | 33 +- src/mod/languages/mod_lua/lua/ldump.c | 43 +- src/mod/languages/mod_lua/lua/lfunc.c | 81 +- src/mod/languages/mod_lua/lua/lfunc.h | 7 +- src/mod/languages/mod_lua/lua/lgc.c | 1660 ++++++++++++------ src/mod/languages/mod_lua/lua/lgc.h | 161 +- src/mod/languages/mod_lua/lua/linit.c | 47 +- src/mod/languages/mod_lua/lua/liolib.c | 510 +++--- src/mod/languages/mod_lua/lua/llex.c | 364 ++-- src/mod/languages/mod_lua/lua/llex.h | 27 +- src/mod/languages/mod_lua/lua/llimits.h | 223 ++- src/mod/languages/mod_lua/lua/lmathlib.c | 96 +- src/mod/languages/mod_lua/lua/lmem.c | 45 +- src/mod/languages/mod_lua/lua/lmem.h | 28 +- src/mod/languages/mod_lua/lua/loadlib.c | 615 ++++--- src/mod/languages/mod_lua/lua/lobject.c | 253 ++- src/mod/languages/mod_lua/lua/lobject.h | 464 +++-- src/mod/languages/mod_lua/lua/lopcodes.c | 31 +- src/mod/languages/mod_lua/lua/lopcodes.h | 106 +- src/mod/languages/mod_lua/lua/loslib.c | 148 +- src/mod/languages/mod_lua/lua/lparser.c | 1033 +++++++---- src/mod/languages/mod_lua/lua/lparser.h | 75 +- src/mod/languages/mod_lua/lua/lstate.c | 276 ++- src/mod/languages/mod_lua/lua/lstate.h | 151 +- src/mod/languages/mod_lua/lua/lstring.c | 194 +- src/mod/languages/mod_lua/lua/lstring.h | 21 +- src/mod/languages/mod_lua/lua/lstrlib.c | 582 +++--- src/mod/languages/mod_lua/lua/ltable.c | 214 +-- src/mod/languages/mod_lua/lua/ltable.h | 15 +- src/mod/languages/mod_lua/lua/ltablib.c | 140 +- src/mod/languages/mod_lua/lua/ltm.c | 20 +- src/mod/languages/mod_lua/lua/ltm.h | 9 +- src/mod/languages/mod_lua/lua/lua.c | 315 ++-- src/mod/languages/mod_lua/lua/lua.h | 226 ++- src/mod/languages/mod_lua/lua/luac.c | 332 +++- src/mod/languages/mod_lua/lua/luaconf.h | 777 +++----- src/mod/languages/mod_lua/lua/lualib.h | 28 +- src/mod/languages/mod_lua/lua/lundump.c | 141 +- src/mod/languages/mod_lua/lua/lundump.h | 22 +- src/mod/languages/mod_lua/lua/lvm.c | 914 +++++----- src/mod/languages/mod_lua/lua/lvm.h | 26 +- src/mod/languages/mod_lua/lua/lzio.c | 34 +- src/mod/languages/mod_lua/lua/lzio.h | 8 +- src/mod/languages/mod_lua/lua/print.c | 227 --- src/mod/languages/mod_lua/mod_lua.cpp | 8 +- src/mod/languages/mod_lua/mod_lua_wrap.cpp | 4 +- 60 files changed, 9201 insertions(+), 6433 deletions(-) delete mode 100644 src/mod/languages/mod_lua/lua/print.c diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 34edfaea93..20e66bb587 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -81,7 +81,7 @@ void Session::setLUA(lua_State * state) if (session && allocated && uuid) { lua_setglobal(L, uuid); - lua_getfield(L, LUA_GLOBALSINDEX, uuid); + lua_getglobal(L, uuid); } } @@ -137,13 +137,13 @@ void Session::do_hangup_hook() return; } - lua_getfield(L, LUA_GLOBALSINDEX, (char *) hangup_func_str); - lua_getfield(L, LUA_GLOBALSINDEX, uuid); + lua_getglobal(L, (char *) hangup_func_str); + lua_getglobal(L, uuid); lua_pushstring(L, hook_state == CS_HANGUP ? "hangup" : "transfer"); if (hangup_func_arg) { - lua_getfield(L, LUA_GLOBALSINDEX, (char *) hangup_func_arg); + lua_getglobal(L, (char *) hangup_func_arg); arg_count++; } @@ -274,8 +274,8 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp char str[3] = ""; int arg_count = 3; - lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_function); - lua_getfield(L, LUA_GLOBALSINDEX, uuid); + lua_getglobal(L, (char *) cb_function); + lua_getglobal(L, uuid); lua_pushstring(L, "dtmf"); @@ -290,7 +290,7 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp lua_rawset(L, -3); if (!zstr(cb_arg)) { - lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_arg); + lua_getglobal(L, (char *) cb_arg); arg_count++; } @@ -308,14 +308,14 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp int arg_count = 3; - lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_function); - lua_getfield(L, LUA_GLOBALSINDEX, uuid); + lua_getglobal(L, (char *) cb_function); + lua_getglobal(L, uuid); lua_pushstring(L, "event"); mod_lua_conjure_event(L, event, "__Input_Event__", 1); - lua_getfield(L, LUA_GLOBALSINDEX, "__Input_Event__"); + lua_getglobal(L, "__Input_Event__"); if (!zstr(cb_arg)) { - lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_arg); + lua_getglobal(L, (char *) cb_arg); arg_count++; } diff --git a/src/mod/languages/mod_lua/hack.diff b/src/mod/languages/mod_lua/hack.diff index fc33ddb9d6..4004459b50 100644 --- a/src/mod/languages/mod_lua/hack.diff +++ b/src/mod/languages/mod_lua/hack.diff @@ -1,38 +1,56 @@ ---- mod_lua_wrap.cpp.orig 2010-09-05 16:39:26.000000000 +0200 -+++ mod_lua_wrap.cpp 2010-09-05 16:39:44.000000000 +0200 -@@ -4913,7 +4913,7 @@ - +--- mod_lua_wrap.cpp.orig 2013-11-13 07:48:40.587304736 +0500 ++++ mod_lua_wrap.cpp 2013-11-13 07:43:09.059309154 +0500 +@@ -6427,7 +6427,7 @@ + SWIG_check_num_args("LUA::Session",0,0) result = (LUA::Session *)new LUA::Session(); SWIG_arg=0; - SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; + SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); return SWIG_arg; - fail: -@@ -4934,7 +4934,7 @@ - arg2=(CoreSession *)SWIG_MustGetPtr(L,2,SWIGTYPE_p_CoreSession,0,2,"new_Session"); + if(0) SWIG_fail; +@@ -6455,7 +6455,7 @@ + result = (LUA::Session *)new LUA::Session(arg1,arg2); SWIG_arg=0; - SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; + SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); return SWIG_arg; - fail: -@@ -4952,7 +4952,7 @@ - arg1 = (char*)lua_tostring(L, 1); + if(0) SWIG_fail; +@@ -6476,7 +6476,7 @@ + arg1 = (char *)lua_tostring(L, 1); result = (LUA::Session *)new LUA::Session(arg1); SWIG_arg=0; - SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; + SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); return SWIG_arg; - fail: -@@ -4970,7 +4970,7 @@ - arg1=(switch_core_session_t *)SWIG_MustGetPtr(L,1,SWIGTYPE_p_switch_core_session_t,0,1,"new_Session"); + if(0) SWIG_fail; +@@ -6501,7 +6501,7 @@ + result = (LUA::Session *)new LUA::Session(arg1); SWIG_arg=0; - SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; + SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); return SWIG_arg; - fail: + if(0) SWIG_fail; +@@ -7913,7 +7913,7 @@ + } + #endif + +-static const struct luaL_reg swig_commands[] = { ++static const struct luaL_Reg swig_commands[] = { + { "setGlobalVariable", _wrap_setGlobalVariable}, + { "getGlobalVariable", _wrap_getGlobalVariable}, + { "consoleLog", _wrap_consoleLog}, +@@ -8325,7 +8325,7 @@ + { + int i; + /* start with global table */ +- lua_pushvalue(L,LUA_GLOBALSINDEX); ++ lua_pushglobaltable(L); + /* SWIG's internal initalisation */ + SWIG_InitializeModule((void*)L); + SWIG_PropagateClientData(); diff --git a/src/mod/languages/mod_lua/lua/Makefile b/src/mod/languages/mod_lua/lua/Makefile index e4a3cd6108..fea895bc06 100644 --- a/src/mod/languages/mod_lua/lua/Makefile +++ b/src/mod/languages/mod_lua/lua/Makefile @@ -1,6 +1,5 @@ -# makefile for building Lua -# see ../INSTALL for installation instructions -# see ../Makefile and luaconf.h for further customization +# Makefile for building Lua +# See ../doc/readme.html for installation and customization instructions. # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= @@ -8,37 +7,46 @@ PLAT= none CC= gcc -CFLAGS= -O2 -Wall $(MYCFLAGS) +CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) +LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) +LIBS= -lm $(SYSLIBS) $(MYLIBS) + AR= ar rcu RANLIB= ranlib RM= rm -f -LIBS= -lm $(MYLIBS) + +SYSCFLAGS= +SYSLDFLAGS= +SYSLIBS= MYCFLAGS= MYLDFLAGS= MYLIBS= +MYOBJS= -# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= +# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris LUA_A= liblua.a -CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ - lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ - lundump.o lvm.o lzio.o -LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ - lstrlib.o loadlib.o linit.o +CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ + lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ + ltm.o lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ + lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o +BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) LUA_T= lua LUA_O= lua.o LUAC_T= luac -LUAC_O= luac.o print.o +LUAC_O= luac.o -ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) +ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O) ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) ALL_A= $(LUA_A) +# Targets start here. default: $(PLAT) all: $(ALL_T) @@ -47,136 +55,133 @@ o: $(ALL_O) a: $(ALL_A) -$(LUA_A): $(CORE_O) $(LIB_O) - $(AR) $@ $? +$(LUA_A): $(BASE_O) + $(AR) $@ $(BASE_O) $(RANLIB) $@ $(LUA_T): $(LUA_O) $(LUA_A) - $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) $(LUAC_T): $(LUAC_O) $(LUA_A) - $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + $(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) clean: $(RM) $(ALL_T) $(ALL_O) depend: - @$(CC) $(CFLAGS) -MM l*.c print.c + @$(CC) $(CFLAGS) -MM l*.c echo: - @echo "PLAT = $(PLAT)" - @echo "CC = $(CC)" - @echo "CFLAGS = $(CFLAGS)" - @echo "AR = $(AR)" - @echo "RANLIB = $(RANLIB)" - @echo "RM = $(RM)" - @echo "MYCFLAGS = $(MYCFLAGS)" - @echo "MYLDFLAGS = $(MYLDFLAGS)" - @echo "MYLIBS = $(MYLIBS)" + @echo "PLAT= $(PLAT)" + @echo "CC= $(CC)" + @echo "CFLAGS= $(CFLAGS)" + @echo "LDFLAGS= $(SYSLDFLAGS)" + @echo "LIBS= $(LIBS)" + @echo "AR= $(AR)" + @echo "RANLIB= $(RANLIB)" + @echo "RM= $(RM)" -# convenience targets for popular platforms +# Convenience targets for popular platforms +ALL= all none: - @echo "Please choose a platform:" + @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" @echo " $(PLATS)" aix: - $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" + $(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall" ansi: - $(MAKE) all MYCFLAGS=-DLUA_ANSI + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_ANSI" bsd: - $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E" freebsd: - $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline" -generic: - $(MAKE) all MYCFLAGS= +generic: $(ALL) linux: - $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline" macosx: - $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" -# use this on Mac OS X 10.3- -# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" mingw: - $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ + $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ - "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe + "SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe $(MAKE) "LUAC_T=luac.exe" luac.exe posix: - $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX" solaris: - $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" + $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" # list targets that do not create files (but not all makes understand .PHONY) .PHONY: all $(PLATS) default o a clean depend echo none # DO NOT DELETE -lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ - lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ - lundump.h lvm.h +lapi.o: lapi.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ + lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h ltable.h lundump.h \ + lvm.h lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ - lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ - ltable.h + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ + lstring.h ltable.h lvm.h +lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h +lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h -ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ - llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ - lfunc.h lstring.h lgc.h ltable.h lvm.h -ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ - lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ - ltable.h lundump.h lvm.h +ldebug.o: ldebug.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ + ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h ldebug.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ + lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h \ + lstring.h ltable.h lundump.h lvm.h ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ - lzio.h lmem.h lundump.h -lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ - lstate.h ltm.h lzio.h + lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ + lstate.h ltm.h lzio.h lmem.h lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ - lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h + lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h -llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ - lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ + lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h ldo.h + ltm.h lzio.h lmem.h ldo.h lgc.h loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h -lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ - ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h +lobject.o: lobject.c lua.h luaconf.h lctype.h llimits.h ldebug.h lstate.h \ + lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h lvm.h lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ - lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ - lfunc.h lstring.h lgc.h ltable.h -lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lfunc.h \ + lstring.h lgc.h ltable.h +lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ + ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ + ltable.h lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ - ltm.h lzio.h lstring.h lgc.h + ltm.h lzio.h lstring.h lgc.h lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h + ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ - lmem.h lstring.h lgc.h ltable.h + lmem.h lstring.h lgc.h ltable.h lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h -luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ - lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ - lundump.h +luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ - llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ - lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ - lzio.h -print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ - ltm.h lzio.h lmem.h lopcodes.h lundump.h + lzio.h -# (end of Makefile) diff --git a/src/mod/languages/mod_lua/lua/lapi.c b/src/mod/languages/mod_lua/lua/lapi.c index 5d5145d2eb..791d85454f 100644 --- a/src/mod/languages/mod_lua/lua/lapi.c +++ b/src/mod/languages/mod_lua/lua/lapi.c @@ -1,12 +1,10 @@ /* -** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ +** $Id: lapi.c,v 2.171 2013/03/16 21:10:18 roberto Exp $ ** Lua API ** See Copyright Notice in lua.h */ -#include -#include #include #include @@ -32,76 +30,80 @@ const char lua_ident[] = - "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" - "$Authors: " LUA_AUTHORS " $\n" - "$URL: www.lua.org $\n"; + "$LuaVersion: " LUA_COPYRIGHT " $" + "$LuaAuthors: " LUA_AUTHORS " $"; +/* value at a non-valid index */ +#define NONVALIDVALUE cast(TValue *, luaO_nilobject) -#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) +/* corresponding test */ +#define isvalid(o) ((o) != luaO_nilobject) -#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) +/* test for pseudo index */ +#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) -#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} +/* test for valid but not pseudo index */ +#define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) + +#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index") + +#define api_checkstackindex(L, i, o) \ + api_check(L, isstackindex(i, o), "index not in the stack") - -static TValue *index2adr (lua_State *L, int idx) { +static TValue *index2addr (lua_State *L, int idx) { + CallInfo *ci = L->ci; if (idx > 0) { - TValue *o = L->base + (idx - 1); - api_check(L, idx <= L->ci->top - L->base); - if (o >= L->top) return cast(TValue *, luaO_nilobject); + TValue *o = ci->func + idx; + api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); + if (o >= L->top) return NONVALIDVALUE; else return o; } - else if (idx > LUA_REGISTRYINDEX) { - api_check(L, idx != 0 && -idx <= L->top - L->base); + else if (!ispseudo(idx)) { /* negative index */ + api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); return L->top + idx; } - else switch (idx) { /* pseudo-indices */ - case LUA_REGISTRYINDEX: return registry(L); - case LUA_ENVIRONINDEX: { - Closure *func = curr_func(L); - sethvalue(L, &L->env, func->c.env); - return &L->env; - } - case LUA_GLOBALSINDEX: return gt(L); - default: { - Closure *func = curr_func(L); - idx = LUA_GLOBALSINDEX - idx; - return (idx <= func->c.nupvalues) - ? &func->c.upvalue[idx-1] - : cast(TValue *, luaO_nilobject); + else if (idx == LUA_REGISTRYINDEX) + return &G(L)->l_registry; + else { /* upvalues */ + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); + if (ttislcf(ci->func)) /* light C function? */ + return NONVALIDVALUE; /* it has no upvalues */ + else { + CClosure *func = clCvalue(ci->func); + return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; } } } -static Table *getcurrenv (lua_State *L) { - if (L->ci == L->base_ci) /* no enclosing function? */ - return hvalue(gt(L)); /* use global table as environment */ - else { - Closure *func = curr_func(L); - return func->c.env; - } -} - - -void luaA_pushobject (lua_State *L, const TValue *o) { - setobj2s(L, L->top, o); - api_incr_top(L); +/* +** to be called by 'lua_checkstack' in protected mode, to grow stack +** capturing memory errors +*/ +static void growstack (lua_State *L, void *ud) { + int size = *(int *)ud; + luaD_growstack(L, size); } LUA_API int lua_checkstack (lua_State *L, int size) { - int res = 1; + int res; + CallInfo *ci = L->ci; lua_lock(L); - if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) - res = 0; /* stack overflow */ - else if (size > 0) { - luaD_checkstack(L, size); - if (L->ci->top < L->top + size) - L->ci->top = L->top + size; + if (L->stack_last - L->top > size) /* stack large enough? */ + res = 1; /* yes; check is OK */ + else { /* no; need to grow stack */ + int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; + if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */ + res = 0; /* no */ + else /* try to grow stack */ + res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK); } + if (res && ci->top < L->top + size) + ci->top = L->top + size; /* adjust frame top */ lua_unlock(L); return res; } @@ -112,8 +114,8 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { if (from == to) return; lua_lock(to); api_checknelems(from, n); - api_check(from, G(from) == G(to)); - api_check(from, to->ci->top - to->top >= n); + api_check(from, G(from) == G(to), "moving among independent states"); + api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); from->top -= n; for (i = 0; i < n; i++) { setobj2s(to, to->top++, from->top + i); @@ -122,11 +124,6 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { } -LUA_API void lua_setlevel (lua_State *from, lua_State *to) { - to->nCcalls = from->nCcalls; -} - - LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { lua_CFunction old; lua_lock(L); @@ -137,16 +134,10 @@ LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { } -LUA_API lua_State *lua_newthread (lua_State *L) { - lua_State *L1; - lua_lock(L); - luaC_checkGC(L); - L1 = luaE_newthread(L); - setthvalue(L, L->top, L1); - api_incr_top(L); - lua_unlock(L); - luai_userstatethread(L, L1); - return L1; +LUA_API const lua_Number *lua_version (lua_State *L) { + static const lua_Number version = LUA_VERSION_NUM; + if (L == NULL) return &version; + else return G(L)->version; } @@ -156,21 +147,32 @@ LUA_API lua_State *lua_newthread (lua_State *L) { */ +/* +** convert an acceptable stack index into an absolute index +*/ +LUA_API int lua_absindex (lua_State *L, int idx) { + return (idx > 0 || ispseudo(idx)) + ? idx + : cast_int(L->top - L->ci->func + idx); +} + + LUA_API int lua_gettop (lua_State *L) { - return cast_int(L->top - L->base); + return cast_int(L->top - (L->ci->func + 1)); } LUA_API void lua_settop (lua_State *L, int idx) { + StkId func = L->ci->func; lua_lock(L); if (idx >= 0) { - api_check(L, idx <= L->stack_last - L->base); - while (L->top < L->base + idx) + api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); + while (L->top < (func + 1) + idx) setnilvalue(L->top++); - L->top = L->base + idx; + L->top = (func + 1) + idx; } else { - api_check(L, -(idx+1) <= (L->top - L->base)); + api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); L->top += idx+1; /* `subtract' index (index is negative) */ } lua_unlock(L); @@ -180,8 +182,8 @@ LUA_API void lua_settop (lua_State *L, int idx) { LUA_API void lua_remove (lua_State *L, int idx) { StkId p; lua_lock(L); - p = index2adr(L, idx); - api_checkvalidindex(L, p); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); while (++p < L->top) setobjs2s(L, p-1, p); L->top--; lua_unlock(L); @@ -192,42 +194,47 @@ LUA_API void lua_insert (lua_State *L, int idx) { StkId p; StkId q; lua_lock(L); - p = index2adr(L, idx); - api_checkvalidindex(L, p); - for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); + for (q = L->top; q > p; q--) /* use L->top as a temporary */ + setobjs2s(L, q, q - 1); setobjs2s(L, p, L->top); lua_unlock(L); } +static void moveto (lua_State *L, TValue *fr, int idx) { + TValue *to = index2addr(L, idx); + api_checkvalidindex(L, to); + setobj(L, to, fr); + if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ + luaC_barrier(L, clCvalue(L->ci->func), fr); + /* LUA_REGISTRYINDEX does not need gc barrier + (collector revisits it before finishing collection) */ +} + + LUA_API void lua_replace (lua_State *L, int idx) { - StkId o; lua_lock(L); - /* explicit test for incompatible code */ - if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) - luaG_runerror(L, "no calling environment"); api_checknelems(L, 1); - o = index2adr(L, idx); - api_checkvalidindex(L, o); - if (idx == LUA_ENVIRONINDEX) { - Closure *func = curr_func(L); - api_check(L, ttistable(L->top - 1)); - func->c.env = hvalue(L->top - 1); - luaC_barrier(L, func, L->top - 1); - } - else { - setobj(L, o, L->top - 1); - if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ - luaC_barrier(L, curr_func(L), L->top - 1); - } + moveto(L, L->top - 1, idx); L->top--; lua_unlock(L); } +LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { + TValue *fr; + lua_lock(L); + fr = index2addr(L, fromidx); + moveto(L, fr, toidx); + lua_unlock(L); +} + + LUA_API void lua_pushvalue (lua_State *L, int idx) { lua_lock(L); - setobj2s(L, L->top, index2adr(L, idx)); + setobj2s(L, L->top, index2addr(L, idx)); api_incr_top(L); lua_unlock(L); } @@ -240,26 +247,26 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { LUA_API int lua_type (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); + StkId o = index2addr(L, idx); + return (isvalid(o) ? ttypenv(o) : LUA_TNONE); } LUA_API const char *lua_typename (lua_State *L, int t) { UNUSED(L); - return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; + return ttypename(t); } LUA_API int lua_iscfunction (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - return iscfunction(o); + StkId o = index2addr(L, idx); + return (ttislcf(o) || (ttisCclosure(o))); } LUA_API int lua_isnumber (lua_State *L, int idx) { TValue n; - const TValue *o = index2adr(L, idx); + const TValue *o = index2addr(L, idx); return tonumber(o, &n); } @@ -271,77 +278,116 @@ LUA_API int lua_isstring (lua_State *L, int idx) { LUA_API int lua_isuserdata (lua_State *L, int idx) { - const TValue *o = index2adr(L, idx); + const TValue *o = index2addr(L, idx); return (ttisuserdata(o) || ttislightuserdata(o)); } LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { - StkId o1 = index2adr(L, index1); - StkId o2 = index2adr(L, index2); - return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 - : luaO_rawequalObj(o1, o2); + StkId o1 = index2addr(L, index1); + StkId o2 = index2addr(L, index2); + return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; } -LUA_API int lua_equal (lua_State *L, int index1, int index2) { - StkId o1, o2; - int i; - lua_lock(L); /* may call tag method */ - o1 = index2adr(L, index1); - o2 = index2adr(L, index2); - i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); - lua_unlock(L); - return i; -} - - -LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { - StkId o1, o2; - int i; - lua_lock(L); /* may call tag method */ - o1 = index2adr(L, index1); - o2 = index2adr(L, index2); - i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 - : luaV_lessthan(L, o1, o2); - lua_unlock(L); - return i; -} - - - -LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { - TValue n; - const TValue *o = index2adr(L, idx); - if (tonumber(o, &n)) - return nvalue(o); +LUA_API void lua_arith (lua_State *L, int op) { + StkId o1; /* 1st operand */ + StkId o2; /* 2nd operand */ + lua_lock(L); + if (op != LUA_OPUNM) /* all other operations expect two operands */ + api_checknelems(L, 2); + else { /* for unary minus, add fake 2nd operand */ + api_checknelems(L, 1); + setobjs2s(L, L->top, L->top - 1); + L->top++; + } + o1 = L->top - 2; + o2 = L->top - 1; + if (ttisnumber(o1) && ttisnumber(o2)) { + setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); + } else - return 0; + luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); + L->top--; + lua_unlock(L); } -LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { +LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { + StkId o1, o2; + int i = 0; + lua_lock(L); /* may call tag method */ + o1 = index2addr(L, index1); + o2 = index2addr(L, index2); + if (isvalid(o1) && isvalid(o2)) { + switch (op) { + case LUA_OPEQ: i = equalobj(L, o1, o2); break; + case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; + case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; + default: api_check(L, 0, "invalid option"); + } + } + lua_unlock(L); + return i; +} + + +LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) { TValue n; - const TValue *o = index2adr(L, idx); + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + if (isnum) *isnum = 1; + return nvalue(o); + } + else { + if (isnum) *isnum = 0; + return 0; + } +} + + +LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); if (tonumber(o, &n)) { lua_Integer res; lua_Number num = nvalue(o); lua_number2integer(res, num); + if (isnum) *isnum = 1; return res; } - else + else { + if (isnum) *isnum = 0; return 0; + } +} + + +LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) { + lua_Unsigned res; + lua_Number num = nvalue(o); + lua_number2unsigned(res, num); + if (isnum) *isnum = 1; + return res; + } + else { + if (isnum) *isnum = 0; + return 0; + } } LUA_API int lua_toboolean (lua_State *L, int idx) { - const TValue *o = index2adr(L, idx); + const TValue *o = index2addr(L, idx); return !l_isfalse(o); } LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { - StkId o = index2adr(L, idx); + StkId o = index2addr(L, idx); if (!ttisstring(o)) { lua_lock(L); /* `luaV_tostring' may create a new string */ if (!luaV_tostring(L, o)) { /* conversion failed? */ @@ -350,7 +396,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { return NULL; } luaC_checkGC(L); - o = index2adr(L, idx); /* previous call may reallocate the stack */ + o = index2addr(L, idx); /* previous call may reallocate the stack */ lua_unlock(L); } if (len != NULL) *len = tsvalue(o)->len; @@ -358,33 +404,29 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { } -LUA_API size_t lua_objlen (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - switch (ttype(o)) { +LUA_API size_t lua_rawlen (lua_State *L, int idx) { + StkId o = index2addr(L, idx); + switch (ttypenv(o)) { case LUA_TSTRING: return tsvalue(o)->len; case LUA_TUSERDATA: return uvalue(o)->len; case LUA_TTABLE: return luaH_getn(hvalue(o)); - case LUA_TNUMBER: { - size_t l; - lua_lock(L); /* `luaV_tostring' may create a new string */ - l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); - lua_unlock(L); - return l; - } default: return 0; } } LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; + StkId o = index2addr(L, idx); + if (ttislcf(o)) return fvalue(o); + else if (ttisCclosure(o)) + return clCvalue(o)->f; + else return NULL; /* not a C function */ } LUA_API void *lua_touserdata (lua_State *L, int idx) { - StkId o = index2adr(L, idx); - switch (ttype(o)) { + StkId o = index2addr(L, idx); + switch (ttypenv(o)) { case LUA_TUSERDATA: return (rawuvalue(o) + 1); case LUA_TLIGHTUSERDATA: return pvalue(o); default: return NULL; @@ -393,16 +435,18 @@ LUA_API void *lua_touserdata (lua_State *L, int idx) { LUA_API lua_State *lua_tothread (lua_State *L, int idx) { - StkId o = index2adr(L, idx); + StkId o = index2addr(L, idx); return (!ttisthread(o)) ? NULL : thvalue(o); } LUA_API const void *lua_topointer (lua_State *L, int idx) { - StkId o = index2adr(L, idx); + StkId o = index2addr(L, idx); switch (ttype(o)) { case LUA_TTABLE: return hvalue(o); - case LUA_TFUNCTION: return clvalue(o); + case LUA_TLCL: return clLvalue(o); + case LUA_TCCL: return clCvalue(o); + case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); case LUA_TTHREAD: return thvalue(o); case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: @@ -429,6 +473,8 @@ LUA_API void lua_pushnil (lua_State *L) { LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { lua_lock(L); setnvalue(L->top, n); + luai_checknum(L, L->top, + luaG_runerror(L, "C API - attempt to push a signaling NaN")); api_incr_top(L); lua_unlock(L); } @@ -442,20 +488,43 @@ LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { } -LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { +LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) { + lua_Number n; lua_lock(L); - luaC_checkGC(L); - setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); + n = lua_unsigned2number(u); + setnvalue(L->top, n); api_incr_top(L); lua_unlock(L); } -LUA_API void lua_pushstring (lua_State *L, const char *s) { - if (s == NULL) +LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_newlstr(L, s, len); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); +} + + +LUA_API const char *lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) { lua_pushnil(L); - else - lua_pushlstring(L, s, strlen(s)); + return NULL; + } + else { + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_new(L, s); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); + } } @@ -484,17 +553,22 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { - Closure *cl; lua_lock(L); - luaC_checkGC(L); - api_checknelems(L, n); - cl = luaF_newCclosure(L, n, getcurrenv(L)); - cl->c.f = fn; - L->top -= n; - while (n--) - setobj2n(L, &cl->c.upvalue[n], L->top+n); - setclvalue(L, L->top, cl); - lua_assert(iswhite(obj2gco(cl))); + if (n == 0) { + setfvalue(L->top, fn); + } + else { + Closure *cl; + api_checknelems(L, n); + api_check(L, n <= MAXUPVAL, "upvalue index too large"); + luaC_checkGC(L); + cl = luaF_newCclosure(L, n); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top + n); + setclCvalue(L, L->top, cl); + } api_incr_top(L); lua_unlock(L); } @@ -531,11 +605,21 @@ LUA_API int lua_pushthread (lua_State *L) { */ +LUA_API void lua_getglobal (lua_State *L, const char *var) { + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_gettable(L, gt, L->top - 1, L->top - 1); + lua_unlock(L); +} + + LUA_API void lua_gettable (lua_State *L, int idx) { StkId t; lua_lock(L); - t = index2adr(L, idx); - api_checkvalidindex(L, t); + t = index2addr(L, idx); luaV_gettable(L, t, L->top - 1, L->top - 1); lua_unlock(L); } @@ -543,13 +627,11 @@ LUA_API void lua_gettable (lua_State *L, int idx) { LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { StkId t; - TValue key; lua_lock(L); - t = index2adr(L, idx); - api_checkvalidindex(L, t); - setsvalue(L, &key, luaS_new(L, k)); - luaV_gettable(L, t, &key, L->top); + t = index2addr(L, idx); + setsvalue2s(L, L->top, luaS_new(L, k)); api_incr_top(L); + luaV_gettable(L, t, L->top - 1, L->top - 1); lua_unlock(L); } @@ -557,29 +639,46 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { LUA_API void lua_rawget (lua_State *L, int idx) { StkId t; lua_lock(L); - t = index2adr(L, idx); - api_check(L, ttistable(t)); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); lua_unlock(L); } LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { - StkId o; + StkId t; lua_lock(L); - o = index2adr(L, idx); - api_check(L, ttistable(o)); - setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top, luaH_getint(hvalue(t), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { + StkId t; + TValue k; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2s(L, L->top, luaH_get(hvalue(t), &k)); api_incr_top(L); lua_unlock(L); } LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + Table *t; lua_lock(L); luaC_checkGC(L); - sethvalue(L, L->top, luaH_new(L, narray, nrec)); + t = luaH_new(L); + sethvalue(L, L->top, t); api_incr_top(L); + if (narray > 0 || nrec > 0) + luaH_resize(L, t, narray, nrec); lua_unlock(L); } @@ -589,8 +688,8 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { Table *mt = NULL; int res; lua_lock(L); - obj = index2adr(L, objindex); - switch (ttype(obj)) { + obj = index2addr(L, objindex); + switch (ttypenv(obj)) { case LUA_TTABLE: mt = hvalue(obj)->metatable; break; @@ -598,7 +697,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { mt = uvalue(obj)->metatable; break; default: - mt = G(L)->mt[ttype(obj)]; + mt = G(L)->mt[ttypenv(obj)]; break; } if (mt == NULL) @@ -613,25 +712,15 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { } -LUA_API void lua_getfenv (lua_State *L, int idx) { +LUA_API void lua_getuservalue (lua_State *L, int idx) { StkId o; lua_lock(L); - o = index2adr(L, idx); - api_checkvalidindex(L, o); - switch (ttype(o)) { - case LUA_TFUNCTION: - sethvalue(L, L->top, clvalue(o)->c.env); - break; - case LUA_TUSERDATA: - sethvalue(L, L->top, uvalue(o)->env); - break; - case LUA_TTHREAD: - setobj2s(L, L->top, gt(thvalue(o))); - break; - default: - setnilvalue(L->top); - break; - } + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (uvalue(o)->env) { + sethvalue(L, L->top, uvalue(o)->env); + } else + setnilvalue(L->top); api_incr_top(L); lua_unlock(L); } @@ -642,12 +731,24 @@ LUA_API void lua_getfenv (lua_State *L, int idx) { */ +LUA_API void lua_setglobal (lua_State *L, const char *var) { + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + api_checknelems(L, 1); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_settable(L, gt, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); +} + + LUA_API void lua_settable (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); - t = index2adr(L, idx); - api_checkvalidindex(L, t); + t = index2addr(L, idx); luaV_settable(L, t, L->top - 2, L->top - 1); L->top -= 2; /* pop index and value */ lua_unlock(L); @@ -656,14 +757,12 @@ LUA_API void lua_settable (lua_State *L, int idx) { LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { StkId t; - TValue key; lua_lock(L); api_checknelems(L, 1); - t = index2adr(L, idx); - api_checkvalidindex(L, t); - setsvalue(L, &key, luaS_new(L, k)); - luaV_settable(L, t, &key, L->top - 1); - L->top--; /* pop value */ + t = index2addr(L, idx); + setsvalue2s(L, L->top++, luaS_new(L, k)); + luaV_settable(L, t, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ lua_unlock(L); } @@ -672,23 +771,39 @@ LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); - t = index2adr(L, idx); - api_check(L, ttistable(t)); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); - luaC_barriert(L, hvalue(t), L->top-1); + invalidateTMcache(hvalue(t)); + luaC_barrierback(L, gcvalue(t), L->top-1); L->top -= 2; lua_unlock(L); } LUA_API void lua_rawseti (lua_State *L, int idx, int n) { - StkId o; + StkId t; lua_lock(L); api_checknelems(L, 1); - o = index2adr(L, idx); - api_check(L, ttistable(o)); - setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); - luaC_barriert(L, hvalue(o), L->top-1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + luaH_setint(L, hvalue(t), n, L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { + StkId t; + TValue k; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top - 1); L->top--; lua_unlock(L); } @@ -699,29 +814,32 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { Table *mt; lua_lock(L); api_checknelems(L, 1); - obj = index2adr(L, objindex); - api_checkvalidindex(L, obj); + obj = index2addr(L, objindex); if (ttisnil(L->top - 1)) mt = NULL; else { - api_check(L, ttistable(L->top - 1)); + api_check(L, ttistable(L->top - 1), "table expected"); mt = hvalue(L->top - 1); } - switch (ttype(obj)) { + switch (ttypenv(obj)) { case LUA_TTABLE: { hvalue(obj)->metatable = mt; - if (mt) - luaC_objbarriert(L, hvalue(obj), mt); + if (mt) { + luaC_objbarrierback(L, gcvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } break; } case LUA_TUSERDATA: { uvalue(obj)->metatable = mt; - if (mt) + if (mt) { luaC_objbarrier(L, rawuvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } break; } default: { - G(L)->mt[ttype(obj)] = mt; + G(L)->mt[ttypenv(obj)] = mt; break; } } @@ -731,32 +849,21 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { } -LUA_API int lua_setfenv (lua_State *L, int idx) { +LUA_API void lua_setuservalue (lua_State *L, int idx) { StkId o; - int res = 1; lua_lock(L); api_checknelems(L, 1); - o = index2adr(L, idx); - api_checkvalidindex(L, o); - api_check(L, ttistable(L->top - 1)); - switch (ttype(o)) { - case LUA_TFUNCTION: - clvalue(o)->c.env = hvalue(L->top - 1); - break; - case LUA_TUSERDATA: - uvalue(o)->env = hvalue(L->top - 1); - break; - case LUA_TTHREAD: - sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); - break; - default: - res = 0; - break; + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (ttisnil(L->top - 1)) + uvalue(o)->env = NULL; + else { + api_check(L, ttistable(L->top - 1), "table expected"); + uvalue(o)->env = hvalue(L->top - 1); + luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); } - if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); L->top--; lua_unlock(L); - return res; } @@ -765,21 +872,37 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { */ -#define adjustresults(L,nres) \ - { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } - - #define checkresults(L,na,nr) \ - api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) - + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ + "results from function overflow current stack size") -LUA_API void lua_call (lua_State *L, int nargs, int nresults) { + +LUA_API int lua_getctx (lua_State *L, int *ctx) { + if (L->ci->callstatus & CIST_YIELDED) { + if (ctx) *ctx = L->ci->u.c.ctx; + return L->ci->u.c.status; + } + else return LUA_OK; +} + + +LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k) { StkId func; lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); func = L->top - (nargs+1); - luaD_call(L, func, nresults); + if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ + L->ci->u.c.k = k; /* save continuation */ + L->ci->u.c.ctx = ctx; /* save context */ + luaD_call(L, func, nresults, 1); /* do the call */ + } + else /* no continuation or no yieldable */ + luaD_call(L, func, nresults, 0); /* just do the call */ adjustresults(L, nresults); lua_unlock(L); } @@ -797,76 +920,75 @@ struct CallS { /* data to `f_call' */ static void f_call (lua_State *L, void *ud) { struct CallS *c = cast(struct CallS *, ud); - luaD_call(L, c->func, c->nresults); + luaD_call(L, c->func, c->nresults, 0); } -LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { +LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k) { struct CallS c; int status; ptrdiff_t func; lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); api_checknelems(L, nargs+1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); if (errfunc == 0) func = 0; else { - StkId o = index2adr(L, errfunc); - api_checkvalidindex(L, o); + StkId o = index2addr(L, errfunc); + api_checkstackindex(L, errfunc, o); func = savestack(L, o); } c.func = L->top - (nargs+1); /* function to be called */ - c.nresults = nresults; - status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ + c.nresults = nresults; /* do a 'conventional' protected call */ + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + } + else { /* prepare continuation (call is already protected by 'resume') */ + CallInfo *ci = L->ci; + ci->u.c.k = k; /* save continuation */ + ci->u.c.ctx = ctx; /* save context */ + /* save information for error recovery */ + ci->extra = savestack(L, c.func); + ci->u.c.old_allowhook = L->allowhook; + ci->u.c.old_errfunc = L->errfunc; + L->errfunc = func; + /* mark that function may do error recovery */ + ci->callstatus |= CIST_YPCALL; + luaD_call(L, c.func, nresults, 1); /* do the call */ + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + status = LUA_OK; /* if it is here, there were no errors */ + } adjustresults(L, nresults); lua_unlock(L); return status; } -/* -** Execute a protected C call. -*/ -struct CCallS { /* data to `f_Ccall' */ - lua_CFunction func; - void *ud; -}; - - -static void f_Ccall (lua_State *L, void *ud) { - struct CCallS *c = cast(struct CCallS *, ud); - Closure *cl; - cl = luaF_newCclosure(L, 0, getcurrenv(L)); - cl->c.f = c->func; - setclvalue(L, L->top, cl); /* push function */ - api_incr_top(L); - setpvalue(L->top, c->ud); /* push only argument */ - api_incr_top(L); - luaD_call(L, L->top - 2, 0); -} - - -LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { - struct CCallS c; - int status; - lua_lock(L); - c.func = func; - c.ud = ud; - status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); - lua_unlock(L); - return status; -} - - LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, - const char *chunkname) { + const char *chunkname, const char *mode) { ZIO z; int status; lua_lock(L); if (!chunkname) chunkname = "?"; luaZ_init(L, &z, reader, data); - status = luaD_protectedparser(L, &z, chunkname); + status = luaD_protectedparser(L, &z, chunkname, mode); + if (status == LUA_OK) { /* no errors? */ + LClosure *f = clLvalue(L->top - 1); /* get newly created function */ + if (f->nupvalues == 1) { /* does it have one upvalue? */ + /* get global table from registry */ + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ + setobj(L, f->upvals[0]->v, gt); + luaC_barrier(L, f->upvals[0], gt); + } + } lua_unlock(L); return status; } @@ -879,7 +1001,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { api_checknelems(L, 1); o = L->top - 1; if (isLfunction(o)) - status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); + status = luaU_dump(L, getproto(o), writer, data, 0); else status = 1; lua_unlock(L); @@ -887,7 +1009,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { } -LUA_API int lua_status (lua_State *L) { +LUA_API int lua_status (lua_State *L) { return L->status; } @@ -903,38 +1025,40 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g = G(L); switch (what) { case LUA_GCSTOP: { - g->GCthreshold = MAX_LUMEM; + g->gcrunning = 0; break; } case LUA_GCRESTART: { - g->GCthreshold = g->totalbytes; + luaE_setdebt(g, 0); + g->gcrunning = 1; break; } case LUA_GCCOLLECT: { - luaC_fullgc(L); + luaC_fullgc(L, 0); break; } case LUA_GCCOUNT: { /* GC values are expressed in Kbytes: #bytes/2^10 */ - res = cast_int(g->totalbytes >> 10); + res = cast_int(gettotalbytes(g) >> 10); break; } case LUA_GCCOUNTB: { - res = cast_int(g->totalbytes & 0x3ff); + res = cast_int(gettotalbytes(g) & 0x3ff); break; } case LUA_GCSTEP: { - lu_mem a = (cast(lu_mem, data) << 10); - if (a <= g->totalbytes) - g->GCthreshold = g->totalbytes - a; - else - g->GCthreshold = 0; - while (g->GCthreshold <= g->totalbytes) { - luaC_step(L); - if (g->gcstate == GCSpause) { /* end of cycle? */ - res = 1; /* signal it */ - break; - } + if (g->gckind == KGC_GEN) { /* generational mode? */ + res = (g->GCestimate == 0); /* true if it will do major collection */ + luaC_forcestep(L); /* do a single step */ + } + else { + lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE; + if (g->gcrunning) + debt += g->GCdebt; /* include current debt */ + luaE_setdebt(g, debt); + luaC_forcestep(L); + if (g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ } break; } @@ -943,11 +1067,28 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { g->gcpause = data; break; } + case LUA_GCSETMAJORINC: { + res = g->gcmajorinc; + g->gcmajorinc = data; + break; + } case LUA_GCSETSTEPMUL: { res = g->gcstepmul; g->gcstepmul = data; break; } + case LUA_GCISRUNNING: { + res = g->gcrunning; + break; + } + case LUA_GCGEN: { /* change collector to generational mode */ + luaC_changemode(L, KGC_GEN); + break; + } + case LUA_GCINC: { /* change collector to incremental mode */ + luaC_changemode(L, KGC_NORMAL); + break; + } default: res = -1; /* invalid option */ } lua_unlock(L); @@ -965,7 +1106,7 @@ LUA_API int lua_error (lua_State *L) { lua_lock(L); api_checknelems(L, 1); luaG_errormsg(L); - lua_unlock(L); + /* code unreachable; will unlock when control actually leaves the kernel */ return 0; /* to avoid warnings */ } @@ -974,8 +1115,8 @@ LUA_API int lua_next (lua_State *L, int idx) { StkId t; int more; lua_lock(L); - t = index2adr(L, idx); - api_check(L, ttistable(t)); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); more = luaH_next(L, hvalue(t), L->top - 1); if (more) { api_incr_top(L); @@ -992,8 +1133,7 @@ LUA_API void lua_concat (lua_State *L, int n) { api_checknelems(L, n); if (n >= 2) { luaC_checkGC(L); - luaV_concat(L, n, cast_int(L->top - L->base) - 1); - L->top -= (n-1); + luaV_concat(L, n); } else if (n == 0) { /* push empty string */ setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); @@ -1004,6 +1144,16 @@ LUA_API void lua_concat (lua_State *L, int n) { } +LUA_API void lua_len (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_objlen(L, L->top, t); + api_incr_top(L); + lua_unlock(L); +} + + LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { lua_Alloc f; lua_lock(L); @@ -1026,7 +1176,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { Udata *u; lua_lock(L); luaC_checkGC(L); - u = luaS_newudata(L, size, getcurrenv(L)); + u = luaS_newudata(L, size, NULL); setuvalue(L, L->top, u); api_incr_top(L); lua_unlock(L); @@ -1035,30 +1185,36 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { - -static const char *aux_upvalue (StkId fi, int n, TValue **val) { - Closure *f; - if (!ttisfunction(fi)) return NULL; - f = clvalue(fi); - if (f->c.isC) { - if (!(1 <= n && n <= f->c.nupvalues)) return NULL; - *val = &f->c.upvalue[n-1]; - return ""; - } - else { - Proto *p = f->l.p; - if (!(1 <= n && n <= p->sizeupvalues)) return NULL; - *val = f->l.upvals[n-1]->v; - return getstr(p->upvalues[n-1]); +static const char *aux_upvalue (StkId fi, int n, TValue **val, + GCObject **owner) { + switch (ttype(fi)) { + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + if (!(1 <= n && n <= f->nupvalues)) return NULL; + *val = &f->upvalue[n-1]; + if (owner) *owner = obj2gco(f); + return ""; + } + case LUA_TLCL: { /* Lua closure */ + LClosure *f = clLvalue(fi); + TString *name; + Proto *p = f->p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->upvals[n-1]->v; + if (owner) *owner = obj2gco(f->upvals[n - 1]); + name = p->upvalues[n-1].name; + return (name == NULL) ? "" : getstr(name); + } + default: return NULL; /* not a closure */ } } LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { const char *name; - TValue *val; + TValue *val = NULL; /* to avoid warnings */ lua_lock(L); - name = aux_upvalue(index2adr(L, funcindex), n, &val); + name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); if (name) { setobj2s(L, L->top, val); api_incr_top(L); @@ -1070,18 +1226,59 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { const char *name; - TValue *val; + TValue *val = NULL; /* to avoid warnings */ + GCObject *owner = NULL; /* to avoid warnings */ StkId fi; lua_lock(L); - fi = index2adr(L, funcindex); + fi = index2addr(L, funcindex); api_checknelems(L, 1); - name = aux_upvalue(fi, n, &val); + name = aux_upvalue(fi, n, &val, &owner); if (name) { L->top--; setobj(L, val, L->top); - luaC_barrier(L, clvalue(fi), L->top); + luaC_barrier(L, owner, L->top); } lua_unlock(L); return name; } + +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { + LClosure *f; + StkId fi = index2addr(L, fidx); + api_check(L, ttisLclosure(fi), "Lua function expected"); + f = clLvalue(fi); + api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); + if (pf) *pf = f; + return &f->upvals[n - 1]; /* get its upvalue pointer */ +} + + +LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { + StkId fi = index2addr(L, fidx); + switch (ttype(fi)) { + case LUA_TLCL: { /* lua closure */ + return *getupvalref(L, fidx, n, NULL); + } + case LUA_TCCL: { /* C closure */ + CClosure *f = clCvalue(fi); + api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); + return &f->upvalue[n - 1]; + } + default: { + api_check(L, 0, "closure expected"); + return NULL; + } + } +} + + +LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, + int fidx2, int n2) { + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + *up1 = *up2; + luaC_objbarrier(L, f1, *up2); +} + diff --git a/src/mod/languages/mod_lua/lua/lapi.h b/src/mod/languages/mod_lua/lua/lapi.h index 2c3fab244e..0909a3911d 100644 --- a/src/mod/languages/mod_lua/lua/lapi.h +++ b/src/mod/languages/mod_lua/lua/lapi.h @@ -1,5 +1,5 @@ /* -** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lapi.h,v 2.7 2009/11/27 15:37:59 roberto Exp $ ** Auxiliary functions from Lua API ** See Copyright Notice in lua.h */ @@ -8,9 +8,17 @@ #define lapi_h -#include "lobject.h" +#include "llimits.h" +#include "lstate.h" +#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ + "stack overflow");} + +#define adjustresults(L,nres) \ + { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } + +#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ + "not enough elements in the stack") -LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); #endif diff --git a/src/mod/languages/mod_lua/lua/lauxlib.c b/src/mod/languages/mod_lua/lua/lauxlib.c index 10f14e2c08..2e989d661b 100644 --- a/src/mod/languages/mod_lua/lua/lauxlib.c +++ b/src/mod/languages/mod_lua/lua/lauxlib.c @@ -1,11 +1,10 @@ /* -** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ +** $Id: lauxlib.c,v 1.248 2013/03/21 13:54:57 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ -#include #include #include #include @@ -25,12 +24,124 @@ #include "lauxlib.h" -#define FREELIST_REF 0 /* free list of references */ +/* +** {====================================================== +** Traceback +** ======================================================= +*/ -/* convert a stack index to positive */ -#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ - lua_gettop(L) + (i) + 1) +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + + + +/* +** search for 'objidx' in table at index -1. +** return 1 + string at top if find a good name. +*/ +static int findfield (lua_State *L, int objidx, int level) { + if (level == 0 || !lua_istable(L, -1)) + return 0; /* not found */ + lua_pushnil(L); /* start 'next' loop */ + while (lua_next(L, -2)) { /* for each pair in table */ + if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } + else if (findfield(L, objidx, level - 1)) { /* try recursively */ + lua_remove(L, -2); /* remove table (but keep name) */ + lua_pushliteral(L, "."); + lua_insert(L, -2); /* place '.' between the two names */ + lua_concat(L, 3); + return 1; + } + } + lua_pop(L, 1); /* remove value */ + } + return 0; /* not found */ +} + + +static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { + int top = lua_gettop(L); + lua_getinfo(L, "f", ar); /* push function */ + lua_pushglobaltable(L); + if (findfield(L, top + 1, 2)) { + lua_copy(L, -1, top + 1); /* move name to proper place */ + lua_pop(L, 2); /* remove pushed values */ + return 1; + } + else { + lua_settop(L, top); /* remove function and global table */ + return 0; + } +} + + +static void pushfuncname (lua_State *L, lua_Debug *ar) { + if (*ar->namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, "function " LUA_QS, ar->name); + else if (*ar->what == 'm') /* main? */ + lua_pushliteral(L, "main chunk"); + else if (*ar->what == 'C') { + if (pushglobalfuncname(L, ar)) { + lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ + } + else + lua_pushliteral(L, "?"); + } + else + lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); +} + + +static int countlevels (lua_State *L) { + lua_Debug ar; + int li = 1, le = 1; + /* find an upper bound */ + while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } + /* do a binary search */ + while (li < le) { + int m = (li + le)/2; + if (lua_getstack(L, m, &ar)) li = m + 1; + else le = m; + } + return le - 1; +} + + +LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, + const char *msg, int level) { + lua_Debug ar; + int top = lua_gettop(L); + int numlevels = countlevels(L1); + int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; + if (msg) lua_pushfstring(L, "%s\n", msg); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level == mark) { /* too many levels? */ + lua_pushliteral(L, "\n\t..."); /* add a '...' */ + level = numlevels - LEVELS2; /* and skip to last ones */ + } + else { + lua_getinfo(L1, "Slnt", &ar); + lua_pushfstring(L, "\n\t%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + lua_pushliteral(L, " in "); + pushfuncname(L, &ar); + if (ar.istailcall) + lua_pushliteral(L, "\n\t(...tail calls...)"); + lua_concat(L, lua_gettop(L) - top); + } + } + lua_concat(L, lua_gettop(L) - top); +} + +/* }====================================================== */ /* @@ -39,7 +150,6 @@ ** ======================================================= */ - LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { lua_Debug ar; if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ @@ -52,13 +162,13 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { ar.name, extramsg); } if (ar.name == NULL) - ar.name = "?"; + ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", narg, ar.name, extramsg); } -LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { +static int typeerror (lua_State *L, int narg, const char *tname) { const char *msg = lua_pushfstring(L, "%s expected, got %s", tname, luaL_typename(L, narg)); return luaL_argerror(L, narg, msg); @@ -66,7 +176,7 @@ LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { static void tag_error (lua_State *L, int narg, int tag) { - luaL_typerror(L, narg, lua_typename(L, tag)); + typeerror(L, narg, lua_typename(L, tag)); } @@ -93,9 +203,120 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { return lua_error(L); } + +LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { + int en = errno; /* calls to Lua API may change this value */ + if (stat) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (fname) + lua_pushfstring(L, "%s: %s", fname, strerror(en)); + else + lua_pushstring(L, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +#if !defined(inspectstat) /* { */ + +#if defined(LUA_USE_POSIX) + +#include + +/* +** use appropriate macros to interpret 'pclose' return status +*/ +#define inspectstat(stat,what) \ + if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ + else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } + +#else + +#define inspectstat(stat,what) /* no op */ + +#endif + +#endif /* } */ + + +LUALIB_API int luaL_execresult (lua_State *L, int stat) { + const char *what = "exit"; /* type of termination */ + if (stat == -1) /* error? */ + return luaL_fileresult(L, 0, NULL); + else { + inspectstat(stat, what); /* interpret result */ + if (*what == 'e' && stat == 0) /* successful termination? */ + lua_pushboolean(L, 1); + else + lua_pushnil(L); + lua_pushstring(L, what); + lua_pushinteger(L, stat); + return 3; /* return true/nil,what,code */ + } +} + /* }====================================================== */ +/* +** {====================================================== +** Userdata's metatable manipulation +** ======================================================= +*/ + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); /* try to get metatable */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { + luaL_getmetatable(L, tname); + lua_setmetatable(L, -2); +} + + +LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + luaL_getmetatable(L, tname); /* get correct metatable */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ + p = NULL; /* value is a userdata with wrong metatable */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + return NULL; /* value is not a userdata with a metatable */ +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = luaL_testudata(L, ud, tname); + if (p == NULL) typeerror(L, ud, tname); + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Argument check functions +** ======================================================= +*/ + LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]) { const char *name = (def) ? luaL_optstring(L, narg, def) : @@ -109,37 +330,15 @@ LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, } -LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ - if (!lua_isnil(L, -1)) /* name already in use? */ - return 0; /* leave previous value on top, but return 0 */ - lua_pop(L, 1); - lua_newtable(L); /* create metatable */ - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ - return 1; -} - - -LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { - void *p = lua_touserdata(L, ud); - if (p != NULL) { /* value is a userdata? */ - if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ - lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ - if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ - lua_pop(L, 2); /* remove both metatables */ - return p; - } - } +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { + /* keep some extra space to run error routines, if needed */ + const int extra = LUA_MINSTACK; + if (!lua_checkstack(L, space + extra)) { + if (msg) + luaL_error(L, "stack overflow (%s)", msg); + else + luaL_error(L, "stack overflow"); } - luaL_typerror(L, ud, tname); /* else error */ - return NULL; /* to avoid warnings */ -} - - -LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { - if (!lua_checkstack(L, space)) - luaL_error(L, "stack overflow (%s)", mes); } @@ -174,8 +373,9 @@ LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { - lua_Number d = lua_tonumber(L, narg); - if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + int isnum; + lua_Number d = lua_tonumberx(L, narg, &isnum); + if (!isnum) tag_error(L, narg, LUA_TNUMBER); return d; } @@ -187,8 +387,18 @@ LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { - lua_Integer d = lua_tointeger(L, narg); - if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + int isnum; + lua_Integer d = lua_tointegerx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) { + int isnum; + lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); + if (!isnum) tag_error(L, narg, LUA_TNUMBER); return d; } @@ -200,6 +410,292 @@ LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, } +LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, + lua_Unsigned def) { + return luaL_opt(L, luaL_checkunsigned, narg, def); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +/* +** check whether buffer is using a userdata on the stack as a temporary +** buffer +*/ +#define buffonstack(B) ((B)->b != (B)->initb) + + +/* +** returns a pointer to a free area with at least 'sz' bytes +*/ +LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { + lua_State *L = B->L; + if (B->size - B->n < sz) { /* not enough space? */ + char *newbuff; + size_t newsize = B->size * 2; /* double buffer size */ + if (newsize - B->n < sz) /* not big enough? */ + newsize = B->n + sz; + if (newsize < B->n || newsize - B->n < sz) + luaL_error(L, "buffer too large"); + /* create larger buffer */ + newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char)); + /* move content to new buffer */ + memcpy(newbuff, B->b, B->n * sizeof(char)); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ + B->b = newbuff; + B->size = newsize; + } + return &B->b[B->n]; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + char *b = luaL_prepbuffsize(B, l); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + lua_State *L = B->L; + lua_pushlstring(L, B->b, B->n); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ +} + + +LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { + luaL_addsize(B, sz); + luaL_pushresult(B); +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t l; + const char *s = lua_tolstring(L, -1, &l); + if (buffonstack(B)) + lua_insert(L, -2); /* put value below buffer */ + luaL_addlstring(B, s, l); + lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->b = B->initb; + B->n = 0; + B->size = LUAL_BUFFERSIZE; +} + + +LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { + luaL_buffinit(L, B); + return luaL_prepbuffsize(B, sz); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Reference system +** ======================================================= +*/ + +/* index of free-list header */ +#define freelist 0 + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ + } + else /* no free elements */ + ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int n; /* number of pre-read characters */ + FILE *f; /* file being read */ + char buff[LUAL_BUFFERSIZE]; /* area for reading file */ +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; /* not used */ + if (lf->n > 0) { /* are there pre-read characters to be read? */ + *size = lf->n; /* return them (chars already in buffer) */ + lf->n = 0; /* no more pre-read characters */ + } + else { /* read a block from file */ + /* 'fread' can return > 0 *and* set the EOF flag. If next call to + 'getF' called 'fread', it might still wait for user input. + The next check avoids this problem. */ + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ + } + return lf->buff; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +static int skipBOM (LoadF *lf) { + const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ + int c; + lf->n = 0; + do { + c = getc(lf->f); + if (c == EOF || c != *(const unsigned char *)p++) return c; + lf->buff[lf->n++] = c; /* to be read by the parser */ + } while (*p != '\0'); + lf->n = 0; /* prefix matched; discard it */ + return getc(lf->f); /* return next character */ +} + + +/* +** reads the first character of file 'f' and skips an optional BOM mark +** in its beginning plus its first line if it starts with '#'. Returns +** true if it skipped the first line. In any case, '*cp' has the +** first "valid" character of the file (after the optional BOM and +** a first-line comment). +*/ +static int skipcomment (LoadF *lf, int *cp) { + int c = *cp = skipBOM(lf); + if (c == '#') { /* first line is a comment (Unix exec. file)? */ + do { /* skip first line */ + c = getc(lf->f); + } while (c != EOF && c != '\n') ; + *cp = getc(lf->f); /* skip end-of-line, if present */ + return 1; /* there was a comment */ + } + else return 0; /* no comment */ +} + + +LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, + const char *mode) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + if (skipcomment(&lf, &c)) /* read initial portion */ + lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + skipcomment(&lf, &c); /* re-read initial portion */ + } + if (c != EOF) + lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ + status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; /* not used */ + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, + const char *name, const char *mode) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name, mode); +} + + +LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + +/* }====================================================== */ + + + LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { if (!lua_getmetatable(L, obj)) /* no metatable? */ return 0; @@ -217,7 +713,7 @@ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { - obj = abs_index(L, obj); + obj = lua_absindex(L, obj); if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ return 0; lua_pushvalue(L, obj); @@ -226,138 +722,52 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { } -LUALIB_API void (luaL_register) (lua_State *L, const char *libname, - const luaL_Reg *l) { - luaI_openlib(L, libname, l, 0); +LUALIB_API int luaL_len (lua_State *L, int idx) { + int l; + int isnum; + lua_len(L, idx); + l = (int)lua_tointegerx(L, -1, &isnum); + if (!isnum) + luaL_error(L, "object length is not a number"); + lua_pop(L, 1); /* remove object */ + return l; } -static int libsize (const luaL_Reg *l) { - int size = 0; - for (; l->name; l++) size++; - return size; -} - - -LUALIB_API void luaI_openlib (lua_State *L, const char *libname, - const luaL_Reg *l, int nup) { - if (libname) { - int size = libsize(l); - /* check whether lib already exists */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); - lua_getfield(L, -1, libname); /* get _LOADED[libname] */ - if (!lua_istable(L, -1)) { /* not found? */ - lua_pop(L, 1); /* remove previous result */ - /* try global variable (and create one if it does not exist) */ - if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) - luaL_error(L, "name conflict for module " LUA_QS, libname); - lua_pushvalue(L, -1); - lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ +LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ + switch (lua_type(L, idx)) { + case LUA_TNUMBER: + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, idx), + lua_topointer(L, idx)); + break; } - lua_remove(L, -2); /* remove _LOADED table */ - lua_insert(L, -(nup+1)); /* move library table to below upvalues */ } - for (; l->name; l++) { - int i; - for (i=0; ifunc, nup); - lua_setfield(L, -(nup+2), l->name); - } - lua_pop(L, nup); /* remove upvalues */ + return lua_tolstring(L, -1, len); } - /* ** {====================================================== -** getn-setn: size for arrays +** Compatibility with 5.1 module functions ** ======================================================= */ +#if defined(LUA_COMPAT_MODULE) -#if defined(LUA_COMPAT_GETN) - -static int checkint (lua_State *L, int topop) { - int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; - lua_pop(L, topop); - return n; -} - - -static void getsizes (lua_State *L) { - lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); - if (lua_isnil(L, -1)) { /* no `size' table? */ - lua_pop(L, 1); /* remove nil */ - lua_newtable(L); /* create it */ - lua_pushvalue(L, -1); /* `size' will be its own metatable */ - lua_setmetatable(L, -2); - lua_pushliteral(L, "kv"); - lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ - } -} - - -LUALIB_API void luaL_setn (lua_State *L, int t, int n) { - t = abs_index(L, t); - lua_pushliteral(L, "n"); - lua_rawget(L, t); - if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ - lua_pushliteral(L, "n"); /* use it */ - lua_pushinteger(L, n); - lua_rawset(L, t); - } - else { /* use `sizes' */ - getsizes(L); - lua_pushvalue(L, t); - lua_pushinteger(L, n); - lua_rawset(L, -3); /* sizes[t] = n */ - lua_pop(L, 1); /* remove `sizes' */ - } -} - - -LUALIB_API int luaL_getn (lua_State *L, int t) { - int n; - t = abs_index(L, t); - lua_pushliteral(L, "n"); /* try t.n */ - lua_rawget(L, t); - if ((n = checkint(L, 1)) >= 0) return n; - getsizes(L); /* else try sizes[t] */ - lua_pushvalue(L, t); - lua_rawget(L, -2); - if ((n = checkint(L, 2)) >= 0) return n; - return (int)lua_objlen(L, t); -} - -#endif - -/* }====================================================== */ - - - -LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, - const char *r) { - const char *wild; - size_t l = strlen(p); - luaL_Buffer b; - luaL_buffinit(L, &b); - while ((wild = strstr(s, p)) != NULL) { - luaL_addlstring(&b, s, wild - s); /* push prefix */ - luaL_addstring(&b, r); /* push replacement in place of pattern */ - s = wild + l; /* continue after `p' */ - } - luaL_addstring(&b, s); /* push last suffix */ - luaL_pushresult(&b); - return lua_tostring(L, -1); -} - - -LUALIB_API const char *luaL_findtable (lua_State *L, int idx, - const char *fname, int szhint) { +static const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { const char *e; - lua_pushvalue(L, idx); + if (idx) lua_pushvalue(L, idx); do { e = strchr(fname, '.'); if (e == NULL) e = fname + strlen(fname); @@ -381,252 +791,133 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx, } - /* -** {====================================================== -** Generic Buffer manipulation -** ======================================================= +** Count number of elements in a luaL_Reg list. */ - - -#define bufflen(B) ((B)->p - (B)->buffer) -#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) - -#define LIMIT (LUA_MINSTACK/2) - - -static int emptybuffer (luaL_Buffer *B) { - size_t l = bufflen(B); - if (l == 0) return 0; /* put nothing on stack */ - else { - lua_pushlstring(B->L, B->buffer, l); - B->p = B->buffer; - B->lvl++; - return 1; - } +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l && l->name; l++) size++; + return size; } -static void adjuststack (luaL_Buffer *B) { - if (B->lvl > 1) { - lua_State *L = B->L; - int toget = 1; /* number of levels to concat */ - size_t toplen = lua_strlen(L, -1); - do { - size_t l = lua_strlen(L, -(toget+1)); - if (B->lvl - toget + 1 >= LIMIT || toplen > l) { - toplen += l; - toget++; - } - else break; - } while (toget < B->lvl); - lua_concat(L, toget); - B->lvl = B->lvl - toget + 1; - } -} - - -LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { - if (emptybuffer(B)) - adjuststack(B); - return B->buffer; -} - - -LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { - while (l--) - luaL_addchar(B, *s++); -} - - -LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { - luaL_addlstring(B, s, strlen(s)); -} - - -LUALIB_API void luaL_pushresult (luaL_Buffer *B) { - emptybuffer(B); - lua_concat(B->L, B->lvl); - B->lvl = 1; -} - - -LUALIB_API void luaL_addvalue (luaL_Buffer *B) { - lua_State *L = B->L; - size_t vl; - const char *s = lua_tolstring(L, -1, &vl); - if (vl <= bufffree(B)) { /* fit into buffer? */ - memcpy(B->p, s, vl); /* put it there */ - B->p += vl; - lua_pop(L, 1); /* remove from stack */ - } - else { - if (emptybuffer(B)) - lua_insert(L, -2); /* put buffer before new value */ - B->lvl++; /* add new value into B stack */ - adjuststack(B); - } -} - - -LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { - B->L = L; - B->p = B->buffer; - B->lvl = 0; -} - -/* }====================================================== */ - - -LUALIB_API int luaL_ref (lua_State *L, int t) { - int ref; - t = abs_index(L, t); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); /* remove from stack */ - return LUA_REFNIL; /* `nil' has a unique fixed reference */ - } - lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ - ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ - lua_pop(L, 1); /* remove it from stack */ - if (ref != 0) { /* any free element? */ - lua_rawgeti(L, t, ref); /* remove it from list */ - lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ - } - else { /* no free elements */ - ref = (int)lua_objlen(L, t); - ref++; /* create new reference */ - } - lua_rawseti(L, t, ref); - return ref; -} - - -LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { - if (ref >= 0) { - t = abs_index(L, t); - lua_rawgeti(L, t, FREELIST_REF); - lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ - lua_pushinteger(L, ref); - lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ - } -} - - - /* -** {====================================================== -** Load functions -** ======================================================= +** Find or create a module table with a given name. The function +** first looks at the _LOADED table and, if that fails, try a +** global variable with that name. In any case, leaves on the stack +** the module table. */ - -typedef struct LoadF { - int extraline; - FILE *f; - char buff[LUAL_BUFFERSIZE]; -} LoadF; - - -static const char *getF (lua_State *L, void *ud, size_t *size) { - LoadF *lf = (LoadF *)ud; - (void)L; - if (lf->extraline) { - lf->extraline = 0; - *size = 1; - return "\n"; +LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, + int sizehint) { + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ + lua_getfield(L, -1, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + lua_pushglobaltable(L); + if (luaL_findtable(L, 0, modname, sizehint) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ } - if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); - return (*size > 0) ? lf->buff : NULL; + lua_remove(L, -2); /* remove _LOADED table */ } -static int errfile (lua_State *L, const char *what, int fnameindex) { - const char *serr = strerror(errno); - const char *filename = lua_tostring(L, fnameindex) + 1; - lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); - lua_remove(L, fnameindex); - return LUA_ERRFILE; +LUALIB_API void luaL_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + luaL_checkversion(L); + if (libname) { + luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ + lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ + } + if (l) + luaL_setfuncs(L, l, nup); + else + lua_pop(L, nup); /* remove upvalues */ } - -LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { - LoadF lf; - int status, readstatus; - int c; - int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ - lf.extraline = 0; - if (filename == NULL) { - lua_pushliteral(L, "=stdin"); - lf.f = stdin; - } - else { - lua_pushfstring(L, "@%s", filename); - lf.f = fopen(filename, "r"); - if (lf.f == NULL) return errfile(L, "open", fnameindex); - } - c = getc(lf.f); - if (c == '#') { /* Unix exec. file? */ - lf.extraline = 1; - while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ - if (c == '\n') c = getc(lf.f); - } - if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ - lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ - if (lf.f == NULL) return errfile(L, "reopen", fnameindex); - /* skip eventual `#!...' */ - while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; - lf.extraline = 0; - } - ungetc(c, lf.f); - status = lua_load(L, getF, &lf, lua_tostring(L, -1)); - readstatus = ferror(lf.f); - if (filename) fclose(lf.f); /* close file (even in case of errors) */ - if (readstatus) { - lua_settop(L, fnameindex); /* ignore results from `lua_load' */ - return errfile(L, "read", fnameindex); - } - lua_remove(L, fnameindex); - return status; -} - - -typedef struct LoadS { - const char *s; - size_t size; -} LoadS; - - -static const char *getS (lua_State *L, void *ud, size_t *size) { - LoadS *ls = (LoadS *)ud; - (void)L; - if (ls->size == 0) return NULL; - *size = ls->size; - ls->size = 0; - return ls->s; -} - - -LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, - const char *name) { - LoadS ls; - ls.s = buff; - ls.size = size; - return lua_load(L, getS, &ls, name); -} - - -LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { - return luaL_loadbuffer(L, s, strlen(s), s); -} - - - +#endif /* }====================================================== */ +/* +** set functions from list 'l' into table at top - 'nup'; each +** function gets the 'nup' elements at the top as upvalues. +** Returns with only the table at the stack. +*/ +LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { + luaL_checkversion(L); + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name != NULL; l++) { /* fill the table with given functions */ + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + +/* +** ensure that stack[idx][fname] has a table and push that table +** into the stack +*/ +LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { + lua_getfield(L, idx, fname); + if (lua_istable(L, -1)) return 1; /* table already there */ + else { + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ + } +} + + +/* +** stripped-down 'require'. Calls 'openf' to open a module, +** registers the result in 'package.loaded' table and, if 'glb' +** is true, also registers the result in the global table. +** Leaves resulting module on the top. +*/ +LUALIB_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* open module */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_pushvalue(L, -2); /* make copy of module (call result) */ + lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ + lua_pop(L, 1); /* remove _LOADED table */ + if (glb) { + lua_pushvalue(L, -1); /* copy of 'mod' */ + lua_setglobal(L, modname); /* _G[modname] = module */ + } +} + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { - (void)ud; - (void)osize; + (void)ud; (void)osize; /* not used */ if (nsize == 0) { free(ptr); return NULL; @@ -637,10 +928,9 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { static int panic (lua_State *L) { - (void)L; /* to avoid warnings */ - fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", + luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)); - return 0; + return 0; /* return to Lua to abort */ } @@ -650,3 +940,20 @@ LUALIB_API lua_State *luaL_newstate (void) { return L; } + +LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) { + const lua_Number *v = lua_version(L); + if (v != lua_version(NULL)) + luaL_error(L, "multiple Lua VMs detected"); + else if (*v != ver) + luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", + ver, *v); + /* check conversions number -> integer types */ + lua_pushnumber(L, -(lua_Number)0x1234); + if (lua_tointeger(L, -1) != -0x1234 || + lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) + luaL_error(L, "bad conversion number->int;" + " must recompile Lua with proper settings"); + lua_pop(L, 1); +} + diff --git a/src/mod/languages/mod_lua/lua/lauxlib.h b/src/mod/languages/mod_lua/lua/lauxlib.h index 34258235db..ac4d15fbb9 100644 --- a/src/mod/languages/mod_lua/lua/lauxlib.h +++ b/src/mod/languages/mod_lua/lua/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lauxlib.h,v 1.120 2011/11/29 15:55:08 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -15,18 +15,6 @@ #include "lua.h" -#if defined(LUA_COMPAT_GETN) -LUALIB_API int (luaL_getn) (lua_State *L, int t); -LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); -#else -#define luaL_getn(L,i) ((int)lua_objlen(L, i)) -#define luaL_setn(L,i,j) ((void)0) /* no op! */ -#endif - -#if defined(LUA_COMPAT_OPENLIB) -#define luaI_openlib luaL_openlib -#endif - /* extra error code for `luaL_load' */ #define LUA_ERRFILE (LUA_ERRERR+1) @@ -38,14 +26,12 @@ typedef struct luaL_Reg { } luaL_Reg; +LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); +#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) -LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, - const luaL_Reg *l, int nup); -LUALIB_API void (luaL_register) (lua_State *L, const char *libname, - const luaL_Reg *l); LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); -LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, size_t *l); @@ -57,12 +43,17 @@ LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, lua_Integer def); +LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); +LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, + lua_Unsigned def); LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); LUALIB_API void (luaL_checkany) (lua_State *L, int narg); LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); LUALIB_API void (luaL_where) (lua_State *L, int lvl); @@ -71,25 +62,41 @@ LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, const char *const lst[]); +LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); +LUALIB_API int (luaL_execresult) (lua_State *L, int stat); + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + LUALIB_API int (luaL_ref) (lua_State *L, int t); LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); -LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); -LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, - const char *name); +LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, + const char *mode); + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + +LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); LUALIB_API lua_State *(luaL_newstate) (void); +LUALIB_API int (luaL_len) (lua_State *L, int idx); LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r); -LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, - const char *fname, int szhint); +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); +LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, + const char *msg, int level); +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); /* ** =============================================================== @@ -97,6 +104,12 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, ** =============================================================== */ + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + #define luaL_argcheck(L, cond,numarg,extramsg) \ ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) @@ -118,56 +131,81 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + /* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ - - typedef struct luaL_Buffer { - char *p; /* current position in buffer */ - int lvl; /* number of strings in the stack (level) */ + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ lua_State *L; - char buffer[LUAL_BUFFERSIZE]; + char initb[LUAL_BUFFERSIZE]; /* initial buffer */ } luaL_Buffer; + #define luaL_addchar(B,c) \ - ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ - (*(B)->p++ = (char)(c))) + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) -/* compatibility only */ -#define luaL_putchar(B,c) luaL_addchar(B,c) - -#define luaL_addsize(B,n) ((B)->p += (n)) +#define luaL_addsize(B,s) ((B)->n += (s)) LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); -LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) /* }====================================================== */ -/* compatibility with ref system */ -/* pre-defined references */ -#define LUA_NOREF (-2) -#define LUA_REFNIL (-1) +/* +** {====================================================== +** File handles for IO library +** ======================================================= +*/ -#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ - (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) +/* +** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +** initial structure 'luaL_Stream' (it may contain other fields +** after that initial structure). +*/ -#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) - -#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) +#define LUA_FILEHANDLE "FILE*" -#define luaL_reg luaL_Reg +typedef struct luaL_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ +} luaL_Stream; + +/* }====================================================== */ + + + +/* compatibility with old module system */ +#if defined(LUA_COMPAT_MODULE) + +LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, + int sizehint); +LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); + +#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) + +#endif + #endif diff --git a/src/mod/languages/mod_lua/lua/lbaselib.c b/src/mod/languages/mod_lua/lua/lbaselib.c index 2a4c079d3b..540e9a5cc0 100644 --- a/src/mod/languages/mod_lua/lua/lbaselib.c +++ b/src/mod/languages/mod_lua/lua/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ +** $Id: lbaselib.c,v 1.276 2013/02/21 13:44:53 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -20,60 +20,68 @@ #include "lualib.h" - - -/* -** If your system does not support `stdout', you can just remove this function. -** If you need, you can define your own `print' function, following this -** model but changing `fputs' to put the strings at a proper place -** (a console window or a log file, for instance). -*/ static int luaB_print (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ int i; lua_getglobal(L, "tostring"); for (i=1; i<=n; i++) { const char *s; + size_t l; lua_pushvalue(L, -1); /* function to be called */ lua_pushvalue(L, i); /* value to print */ lua_call(L, 1, 1); - s = lua_tostring(L, -1); /* get result */ + s = lua_tolstring(L, -1, &l); /* get result */ if (s == NULL) - return luaL_error(L, LUA_QL("tostring") " must return a string to " - LUA_QL("print")); - if (i>1) fputs("\t", stdout); - fputs(s, stdout); + return luaL_error(L, + LUA_QL("tostring") " must return a string to " LUA_QL("print")); + if (i>1) luai_writestring("\t", 1); + luai_writestring(s, l); lua_pop(L, 1); /* pop result */ } - fputs("\n", stdout); + luai_writeline(); return 0; } +#define SPACECHARS " \f\n\r\t\v" + static int luaB_tonumber (lua_State *L) { - int base = luaL_optint(L, 2, 10); - if (base == 10) { /* standard conversion */ - luaL_checkany(L, 1); - if (lua_isnumber(L, 1)) { - lua_pushnumber(L, lua_tonumber(L, 1)); + if (lua_isnoneornil(L, 2)) { /* standard conversion */ + int isnum; + lua_Number n = lua_tonumberx(L, 1, &isnum); + if (isnum) { + lua_pushnumber(L, n); return 1; - } + } /* else not a number; must be something */ + luaL_checkany(L, 1); } else { - const char *s1 = luaL_checkstring(L, 1); - char *s2; - unsigned long n; + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *e = s + l; /* end point for 's' */ + int base = luaL_checkint(L, 2); + int neg = 0; luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); - n = strtoul(s1, &s2, base); - if (s1 != s2) { /* at least one valid digit? */ - while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ - if (*s2 == '\0') { /* no invalid trailing characters? */ - lua_pushnumber(L, (lua_Number)n); + s += strspn(s, SPACECHARS); /* skip initial spaces */ + if (*s == '-') { s++; neg = 1; } /* handle signal */ + else if (*s == '+') s++; + if (isalnum((unsigned char)*s)) { + lua_Number n = 0; + do { + int digit = (isdigit((unsigned char)*s)) ? *s - '0' + : toupper((unsigned char)*s) - 'A' + 10; + if (digit >= base) break; /* invalid numeral; force a fail */ + n = n * (lua_Number)base + (lua_Number)digit; + s++; + } while (isalnum((unsigned char)*s)); + s += strspn(s, SPACECHARS); /* skip trailing spaces */ + if (s == e) { /* no invalid trailing characters? */ + lua_pushnumber(L, (neg) ? -n : n); return 1; - } - } + } /* else not a number */ + } /* else not a number */ } - lua_pushnil(L); /* else not a number */ + lua_pushnil(L); /* not a number */ return 1; } @@ -107,57 +115,13 @@ static int luaB_setmetatable (lua_State *L) { luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); if (luaL_getmetafield(L, 1, "__metatable")) - luaL_error(L, "cannot change a protected metatable"); + return luaL_error(L, "cannot change a protected metatable"); lua_settop(L, 2); lua_setmetatable(L, 1); return 1; } -static void getfunc (lua_State *L, int opt) { - if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); - else { - lua_Debug ar; - int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); - luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); - if (lua_getstack(L, level, &ar) == 0) - luaL_argerror(L, 1, "invalid level"); - lua_getinfo(L, "f", &ar); - if (lua_isnil(L, -1)) - luaL_error(L, "no function environment for tail call at level %d", - level); - } -} - - -static int luaB_getfenv (lua_State *L) { - getfunc(L, 1); - if (lua_iscfunction(L, -1)) /* is a C function? */ - lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ - else - lua_getfenv(L, -1); - return 1; -} - - -static int luaB_setfenv (lua_State *L) { - luaL_checktype(L, 2, LUA_TTABLE); - getfunc(L, 0); - lua_pushvalue(L, 2); - if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { - /* change environment of current thread */ - lua_pushthread(L); - lua_insert(L, -2); - lua_setfenv(L, -2); - return 0; - } - else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) - luaL_error(L, - LUA_QL("setfenv") " cannot change environment of given object"); - return 1; -} - - static int luaB_rawequal (lua_State *L) { luaL_checkany(L, 1); luaL_checkany(L, 2); @@ -166,6 +130,15 @@ static int luaB_rawequal (lua_State *L) { } +static int luaB_rawlen (lua_State *L) { + int t = lua_type(L, 1); + luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, + "table or string expected"); + lua_pushinteger(L, lua_rawlen(L, 1)); + return 1; +} + + static int luaB_rawget (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); @@ -184,32 +157,29 @@ static int luaB_rawset (lua_State *L) { } -static int luaB_gcinfo (lua_State *L) { - lua_pushinteger(L, lua_getgccount(L)); - return 1; -} - - static int luaB_collectgarbage (lua_State *L) { static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpause", "setstepmul", NULL}; + "count", "step", "setpause", "setstepmul", + "setmajorinc", "isrunning", "generational", "incremental", NULL}; static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, - LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; - int o = luaL_checkoption(L, 1, "collect", opts); + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; + int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; int ex = luaL_optint(L, 2, 0); - int res = lua_gc(L, optsnum[o], ex); - switch (optsnum[o]) { + int res = lua_gc(L, o, ex); + switch (o) { case LUA_GCCOUNT: { int b = lua_gc(L, LUA_GCCOUNTB, 0); lua_pushnumber(L, res + ((lua_Number)b/1024)); - return 1; + lua_pushinteger(L, b); + return 2; } - case LUA_GCSTEP: { + case LUA_GCSTEP: case LUA_GCISRUNNING: { lua_pushboolean(L, res); return 1; } default: { - lua_pushnumber(L, res); + lua_pushinteger(L, res); return 1; } } @@ -223,6 +193,23 @@ static int luaB_type (lua_State *L) { } +static int pairsmeta (lua_State *L, const char *method, int iszero, + lua_CFunction iter) { + if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ + luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ + lua_pushcfunction(L, iter); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + if (iszero) lua_pushinteger(L, 0); /* and initial value */ + else lua_pushnil(L); + } + else { + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_call(L, 1, 3); /* get 3 values from metamethod */ + } + return 3; +} + + static int luaB_next (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 2); /* create a 2nd argument if there isn't one */ @@ -236,11 +223,7 @@ static int luaB_next (lua_State *L) { static int luaB_pairs (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ - lua_pushvalue(L, 1); /* state, */ - lua_pushnil(L); /* and initial value */ - return 3; + return pairsmeta(L, "__pairs", 0, luaB_next); } @@ -250,23 +233,25 @@ static int ipairsaux (lua_State *L) { i++; /* next value */ lua_pushinteger(L, i); lua_rawgeti(L, 1, i); - return (lua_isnil(L, -1)) ? 0 : 2; + return (lua_isnil(L, -1)) ? 1 : 2; } static int luaB_ipairs (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ - lua_pushvalue(L, 1); /* state, */ - lua_pushinteger(L, 0); /* and initial value */ - return 3; + return pairsmeta(L, "__ipairs", 1, ipairsaux); } -static int load_aux (lua_State *L, int status) { - if (status == 0) /* OK? */ +static int load_aux (lua_State *L, int status, int envidx) { + if (status == LUA_OK) { + if (envidx != 0) { /* 'env' parameter? */ + lua_pushvalue(L, envidx); /* environment for loaded function */ + if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ + lua_pop(L, 1); /* remove 'env' if not used by previous call */ + } return 1; - else { + } + else { /* error (message is on top of the stack) */ lua_pushnil(L); lua_insert(L, -2); /* put before error message */ return 2; /* return nil plus error message */ @@ -274,20 +259,30 @@ static int load_aux (lua_State *L, int status) { } -static int luaB_loadstring (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - const char *chunkname = luaL_optstring(L, 2, s); - return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); -} - - static int luaB_loadfile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); - return load_aux(L, luaL_loadfile(L, fname)); + const char *mode = luaL_optstring(L, 2, NULL); + int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ + int status = luaL_loadfilex(L, fname, mode); + return load_aux(L, status, env); } +/* +** {====================================================== +** Generic Read function +** ======================================================= +*/ + + +/* +** reserved slot, above all arguments, to hold a copy of the returned +** string to avoid it being collected while parsed. 'load' has four +** optional arguments (chunk, source name, mode, and environment). +*/ +#define RESERVEDSLOT 5 + + /* ** Reader for generic `load' function: `lua_load' uses the ** stack for internal stuff, so the reader cannot change the @@ -295,66 +290,66 @@ static int luaB_loadfile (lua_State *L) { ** reserved slot inside the stack. */ static const char *generic_reader (lua_State *L, void *ud, size_t *size) { - (void)ud; /* to avoid warnings */ + (void)(ud); /* not used */ luaL_checkstack(L, 2, "too many nested functions"); lua_pushvalue(L, 1); /* get function */ lua_call(L, 0, 1); /* call it */ if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* pop result */ *size = 0; return NULL; } - else if (lua_isstring(L, -1)) { - lua_replace(L, 3); /* save string in a reserved stack slot */ - return lua_tolstring(L, 3, size); - } - else luaL_error(L, "reader function must return a string"); - return NULL; /* to avoid warnings */ + else if (!lua_isstring(L, -1)) + luaL_error(L, "reader function must return a string"); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tolstring(L, RESERVEDSLOT, size); } static int luaB_load (lua_State *L) { int status; - const char *cname = luaL_optstring(L, 2, "=(load)"); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ - status = lua_load(L, generic_reader, NULL, cname); - return load_aux(L, status); + size_t l; + const char *s = lua_tolstring(L, 1, &l); + const char *mode = luaL_optstring(L, 3, "bt"); + int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ + if (s != NULL) { /* loading a string? */ + const char *chunkname = luaL_optstring(L, 2, s); + status = luaL_loadbufferx(L, s, l, chunkname, mode); + } + else { /* loading from a reader function */ + const char *chunkname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, NULL, chunkname, mode); + } + return load_aux(L, status, env); +} + +/* }====================================================== */ + + +static int dofilecont (lua_State *L) { + return lua_gettop(L) - 1; } static int luaB_dofile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); - int n = lua_gettop(L); - if (luaL_loadfile(L, fname) != 0) lua_error(L); - lua_call(L, 0, LUA_MULTRET); - return lua_gettop(L) - n; + lua_settop(L, 1); + if (luaL_loadfile(L, fname) != LUA_OK) + return lua_error(L); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); + return dofilecont(L); } static int luaB_assert (lua_State *L) { - luaL_checkany(L, 1); if (!lua_toboolean(L, 1)) return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); return lua_gettop(L); } -static int luaB_unpack (lua_State *L) { - int i, e, n; - luaL_checktype(L, 1, LUA_TTABLE); - i = luaL_optint(L, 2, 1); - e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); - if (i > e) return 0; /* empty range */ - n = e - i + 1; /* number of elements */ - if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ - return luaL_error(L, "too many results to unpack"); - lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ - while (i++ < e) /* push arg[i + 1...e] */ - lua_rawgeti(L, 1, i); - return n; -} - - static int luaB_select (lua_State *L) { int n = lua_gettop(L); if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { @@ -371,75 +366,50 @@ static int luaB_select (lua_State *L) { } +static int finishpcall (lua_State *L, int status) { + if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */ + lua_settop(L, 0); /* create space for return values */ + lua_pushboolean(L, 0); + lua_pushstring(L, "stack overflow"); + return 2; /* return false, msg */ + } + lua_pushboolean(L, status); /* first result (status) */ + lua_replace(L, 1); /* put first result in first slot */ + return lua_gettop(L); +} + + +static int pcallcont (lua_State *L) { + int status = lua_getctx(L, NULL); + return finishpcall(L, (status == LUA_YIELD)); +} + + static int luaB_pcall (lua_State *L) { int status; luaL_checkany(L, 1); - status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); - lua_pushboolean(L, (status == 0)); - lua_insert(L, 1); - return lua_gettop(L); /* return status + all results */ + lua_pushnil(L); + lua_insert(L, 1); /* create space for status result */ + status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont); + return finishpcall(L, (status == LUA_OK)); } static int luaB_xpcall (lua_State *L) { int status; - luaL_checkany(L, 2); - lua_settop(L, 2); - lua_insert(L, 1); /* put error function under function to be called */ - status = lua_pcall(L, 0, LUA_MULTRET, 1); - lua_pushboolean(L, (status == 0)); - lua_replace(L, 1); - return lua_gettop(L); /* return status + all results */ + int n = lua_gettop(L); + luaL_argcheck(L, n >= 2, 2, "value expected"); + lua_pushvalue(L, 1); /* exchange function... */ + lua_copy(L, 2, 1); /* ...and error handler */ + lua_replace(L, 2); + status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont); + return finishpcall(L, (status == LUA_OK)); } static int luaB_tostring (lua_State *L) { luaL_checkany(L, 1); - if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ - return 1; /* use its value */ - switch (lua_type(L, 1)) { - case LUA_TNUMBER: - lua_pushstring(L, lua_tostring(L, 1)); - break; - case LUA_TSTRING: - lua_pushvalue(L, 1); - break; - case LUA_TBOOLEAN: - lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); - break; - case LUA_TNIL: - lua_pushliteral(L, "nil"); - break; - default: - lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); - break; - } - return 1; -} - - -static int luaB_newproxy (lua_State *L) { - lua_settop(L, 1); - lua_newuserdata(L, 0); /* create proxy */ - if (lua_toboolean(L, 1) == 0) - return 1; /* no metatable */ - else if (lua_isboolean(L, 1)) { - lua_newtable(L); /* create a new metatable `m' ... */ - lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ - lua_pushboolean(L, 1); - lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ - } - else { - int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ - if (lua_getmetatable(L, 1)) { - lua_rawget(L, lua_upvalueindex(1)); - validproxy = lua_toboolean(L, -1); - lua_pop(L, 1); /* remove value */ - } - luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); - lua_getmetatable(L, 1); /* metatable is valid; get it */ - } - lua_setmetatable(L, 2); + luaL_tolstring(L, 1, NULL); return 1; } @@ -449,205 +419,40 @@ static const luaL_Reg base_funcs[] = { {"collectgarbage", luaB_collectgarbage}, {"dofile", luaB_dofile}, {"error", luaB_error}, - {"gcinfo", luaB_gcinfo}, - {"getfenv", luaB_getfenv}, {"getmetatable", luaB_getmetatable}, + {"ipairs", luaB_ipairs}, {"loadfile", luaB_loadfile}, {"load", luaB_load}, - {"loadstring", luaB_loadstring}, +#if defined(LUA_COMPAT_LOADSTRING) + {"loadstring", luaB_load}, +#endif {"next", luaB_next}, + {"pairs", luaB_pairs}, {"pcall", luaB_pcall}, {"print", luaB_print}, {"rawequal", luaB_rawequal}, + {"rawlen", luaB_rawlen}, {"rawget", luaB_rawget}, {"rawset", luaB_rawset}, {"select", luaB_select}, - {"setfenv", luaB_setfenv}, {"setmetatable", luaB_setmetatable}, {"tonumber", luaB_tonumber}, {"tostring", luaB_tostring}, {"type", luaB_type}, - {"unpack", luaB_unpack}, {"xpcall", luaB_xpcall}, {NULL, NULL} }; -/* -** {====================================================== -** Coroutine library -** ======================================================= -*/ - -#define CO_RUN 0 /* running */ -#define CO_SUS 1 /* suspended */ -#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ -#define CO_DEAD 3 - -static const char *const statnames[] = - {"running", "suspended", "normal", "dead"}; - -static int costatus (lua_State *L, lua_State *co) { - if (L == co) return CO_RUN; - switch (lua_status(co)) { - case LUA_YIELD: - return CO_SUS; - case 0: { - lua_Debug ar; - if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ - return CO_NOR; /* it is running */ - else if (lua_gettop(co) == 0) - return CO_DEAD; - else - return CO_SUS; /* initial state */ - } - default: /* some error occured */ - return CO_DEAD; - } -} - - -static int luaB_costatus (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); - lua_pushstring(L, statnames[costatus(L, co)]); - return 1; -} - - -static int auxresume (lua_State *L, lua_State *co, int narg) { - int status = costatus(L, co); - if (!lua_checkstack(co, narg)) - luaL_error(L, "too many arguments to resume"); - if (status != CO_SUS) { - lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); - return -1; /* error flag */ - } - lua_xmove(L, co, narg); - lua_setlevel(L, co); - status = lua_resume(co, narg); - if (status == 0 || status == LUA_YIELD) { - int nres = lua_gettop(co); - if (!lua_checkstack(L, nres + 1)) - luaL_error(L, "too many results to resume"); - lua_xmove(co, L, nres); /* move yielded values */ - return nres; - } - else { - lua_xmove(co, L, 1); /* move error message */ - return -1; /* error flag */ - } -} - - -static int luaB_coresume (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - int r; - luaL_argcheck(L, co, 1, "coroutine expected"); - r = auxresume(L, co, lua_gettop(L) - 1); - if (r < 0) { - lua_pushboolean(L, 0); - lua_insert(L, -2); - return 2; /* return false + error message */ - } - else { - lua_pushboolean(L, 1); - lua_insert(L, -(r + 1)); - return r + 1; /* return true + `resume' returns */ - } -} - - -static int luaB_auxwrap (lua_State *L) { - lua_State *co = lua_tothread(L, lua_upvalueindex(1)); - int r = auxresume(L, co, lua_gettop(L)); - if (r < 0) { - if (lua_isstring(L, -1)) { /* error object is a string? */ - luaL_where(L, 1); /* add extra info */ - lua_insert(L, -2); - lua_concat(L, 2); - } - lua_error(L); /* propagate error */ - } - return r; -} - - -static int luaB_cocreate (lua_State *L) { - lua_State *NL = lua_newthread(L); - luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, - "Lua function expected"); - lua_pushvalue(L, 1); /* move function to top */ - lua_xmove(L, NL, 1); /* move function from L to NL */ - return 1; -} - - -static int luaB_cowrap (lua_State *L) { - luaB_cocreate(L); - lua_pushcclosure(L, luaB_auxwrap, 1); - return 1; -} - - -static int luaB_yield (lua_State *L) { - return lua_yield(L, lua_gettop(L)); -} - - -static int luaB_corunning (lua_State *L) { - if (lua_pushthread(L)) - lua_pushnil(L); /* main thread is not a coroutine */ - return 1; -} - - -static const luaL_Reg co_funcs[] = { - {"create", luaB_cocreate}, - {"resume", luaB_coresume}, - {"running", luaB_corunning}, - {"status", luaB_costatus}, - {"wrap", luaB_cowrap}, - {"yield", luaB_yield}, - {NULL, NULL} -}; - -/* }====================================================== */ - - -static void auxopen (lua_State *L, const char *name, - lua_CFunction f, lua_CFunction u) { - lua_pushcfunction(L, u); - lua_pushcclosure(L, f, 1); - lua_setfield(L, -2, name); -} - - -static void base_open (lua_State *L) { +LUAMOD_API int luaopen_base (lua_State *L) { /* set global _G */ - lua_pushvalue(L, LUA_GLOBALSINDEX); - lua_setglobal(L, "_G"); + lua_pushglobaltable(L); + lua_pushglobaltable(L); + lua_setfield(L, -2, "_G"); /* open lib into global table */ - luaL_register(L, "_G", base_funcs); + luaL_setfuncs(L, base_funcs, 0); lua_pushliteral(L, LUA_VERSION); - lua_setglobal(L, "_VERSION"); /* set global _VERSION */ - /* `ipairs' and `pairs' need auxliliary functions as upvalues */ - auxopen(L, "ipairs", luaB_ipairs, ipairsaux); - auxopen(L, "pairs", luaB_pairs, luaB_next); - /* `newproxy' needs a weaktable as upvalue */ - lua_createtable(L, 0, 1); /* new table `w' */ - lua_pushvalue(L, -1); /* `w' will be its own metatable */ - lua_setmetatable(L, -2); - lua_pushliteral(L, "kv"); - lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ - lua_pushcclosure(L, luaB_newproxy, 1); - lua_setglobal(L, "newproxy"); /* set global `newproxy' */ -} - - -LUALIB_API int luaopen_base (lua_State *L) { - base_open(L); - luaL_register(L, LUA_COLIBNAME, co_funcs); - return 2; + lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ + return 1; } diff --git a/src/mod/languages/mod_lua/lua/lcode.c b/src/mod/languages/mod_lua/lua/lcode.c index cff626b7fa..56c26ac8aa 100644 --- a/src/mod/languages/mod_lua/lua/lcode.c +++ b/src/mod/languages/mod_lua/lua/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ +** $Id: lcode.c,v 2.62 2012/08/16 17:34:28 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -21,7 +21,9 @@ #include "lobject.h" #include "lopcodes.h" #include "lparser.h" +#include "lstring.h" #include "ltable.h" +#include "lvm.h" #define hasjumps(e) ((e)->t != (e)->f) @@ -34,25 +36,23 @@ static int isnumeral(expdesc *e) { void luaK_nil (FuncState *fs, int from, int n) { Instruction *previous; + int l = from + n - 1; /* last register to set nil */ if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ - if (fs->pc == 0) { /* function start? */ - if (from >= fs->nactvar) - return; /* positions are already clean */ - } - else { - previous = &fs->f->code[fs->pc-1]; - if (GET_OPCODE(*previous) == OP_LOADNIL) { - int pfrom = GETARG_A(*previous); - int pto = GETARG_B(*previous); - if (pfrom <= from && from <= pto+1) { /* can connect both? */ - if (from+n-1 > pto) - SETARG_B(*previous, from+n-1); - return; - } + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pl = pfrom + GETARG_B(*previous); + if ((pfrom <= from && from <= pl + 1) || + (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ + if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ + if (pl > l) l = pl; /* l = max(l, pl) */ + SETARG_A(*previous, from); + SETARG_B(*previous, l - from); + return; } - } + } /* else go through */ } - luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ + luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ } @@ -176,6 +176,19 @@ void luaK_patchlist (FuncState *fs, int list, int target) { } +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { + level++; /* argument is +1 to reserve 0 as non-op */ + while (list != NO_JUMP) { + int next = getjump(fs, list); + lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && + (GETARG_A(fs->f->code[list]) == 0 || + GETARG_A(fs->f->code[list]) >= level)); + SETARG_A(fs->f->code[list], level); + list = next; + } +} + + void luaK_patchtohere (FuncState *fs, int list) { luaK_getlabel(fs); luaK_concat(fs, &fs->jpc, list); @@ -196,6 +209,55 @@ void luaK_concat (FuncState *fs, int *l1, int l2) { } +static int luaK_code (FuncState *fs, Instruction i) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "opcodes"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "opcodes"); + f->lineinfo[fs->pc] = fs->ls->lastline; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); + return luaK_code(fs, CREATE_ABC(o, a, b, c)); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, bc)); +} + + +static int codeextraarg (FuncState *fs, int a) { + lua_assert(a <= MAXARG_Ax); + return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); +} + + +int luaK_codek (FuncState *fs, int reg, int k) { + if (k <= MAXARG_Bx) + return luaK_codeABx(fs, OP_LOADK, reg, k); + else { + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); + codeextraarg(fs, k); + return p; + } +} + + void luaK_checkstack (FuncState *fs, int n) { int newstack = fs->freereg + n; if (newstack > fs->f->maxstacksize) { @@ -222,42 +284,59 @@ static void freereg (FuncState *fs, int reg) { static void freeexp (FuncState *fs, expdesc *e) { if (e->k == VNONRELOC) - freereg(fs, e->u.s.info); + freereg(fs, e->u.info); } -static int addk (FuncState *fs, TValue *k, TValue *v) { - lua_State *L = fs->L; - TValue *idx = luaH_set(L, fs->h, k); +static int addk (FuncState *fs, TValue *key, TValue *v) { + lua_State *L = fs->ls->L; + TValue *idx = luaH_set(L, fs->h, key); Proto *f = fs->f; - int oldsize = f->sizek; + int k, oldsize; if (ttisnumber(idx)) { - lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); - return cast_int(nvalue(idx)); - } - else { /* constant not found; create a new entry */ - setnvalue(idx, cast_num(fs->nk)); - luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, - MAXARG_Bx, "constant table overflow"); - while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); - setobj(L, &f->k[fs->nk], v); - luaC_barrier(L, f, v); - return fs->nk++; + lua_Number n = nvalue(idx); + lua_number2int(k, n); + if (luaV_rawequalobj(&f->k[k], v)) + return k; + /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); + go through and create a new entry for this value */ } + /* constant not found; create a new entry */ + oldsize = f->sizek; + k = fs->nk; + /* numerical value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setnvalue(idx, cast_num(k)); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[k], v); + fs->nk++; + luaC_barrier(L, f, v); + return k; } int luaK_stringK (FuncState *fs, TString *s) { TValue o; - setsvalue(fs->L, &o, s); + setsvalue(fs->ls->L, &o, s); return addk(fs, &o, &o); } int luaK_numberK (FuncState *fs, lua_Number r) { + int n; + lua_State *L = fs->ls->L; TValue o; setnvalue(&o, r); - return addk(fs, &o, &o); + if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ + /* use raw representation as key to avoid numeric problems */ + setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); + n = addk(fs, L->top - 1, &o); + L->top--; + } + else + n = addk(fs, &o, &o); /* regular case */ + return n; } @@ -272,7 +351,7 @@ static int nilK (FuncState *fs) { TValue k, v; setnilvalue(&v); /* cannot use nil as key; instead use table itself to represent nil */ - sethvalue(fs->L, &k, fs->h); + sethvalue(fs->ls->L, &k, fs->h); return addk(fs, &k, &v); } @@ -292,7 +371,7 @@ void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { void luaK_setoneret (FuncState *fs, expdesc *e) { if (e->k == VCALL) { /* expression is an open function call? */ e->k = VNONRELOC; - e->u.s.info = GETARG_A(getcode(fs, e)); + e->u.info = GETARG_A(getcode(fs, e)); } else if (e->k == VVARARG) { SETARG_B(getcode(fs, e), 2); @@ -308,19 +387,18 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { break; } case VUPVAL: { - e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); - e->k = VRELOCABLE; - break; - } - case VGLOBAL: { - e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); + e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); e->k = VRELOCABLE; break; } case VINDEXED: { - freereg(fs, e->u.s.aux); - freereg(fs, e->u.s.info); - e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); + OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ + freereg(fs, e->u.ind.idx); + if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ + freereg(fs, e->u.ind.t); + op = OP_GETTABLE; + } + e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); e->k = VRELOCABLE; break; } @@ -347,16 +425,16 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { luaK_nil(fs, reg, 1); break; } - case VFALSE: case VTRUE: { + case VFALSE: case VTRUE: { luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); break; } case VK: { - luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); + luaK_codek(fs, reg, e->u.info); break; } case VKNUM: { - luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); + luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); break; } case VRELOCABLE: { @@ -365,8 +443,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { break; } case VNONRELOC: { - if (reg != e->u.s.info) - luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); + if (reg != e->u.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); break; } default: { @@ -374,7 +452,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { return; /* nothing to do... */ } } - e->u.s.info = reg; + e->u.info = reg; e->k = VNONRELOC; } @@ -390,7 +468,7 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { static void exp2reg (FuncState *fs, expdesc *e, int reg) { discharge2reg(fs, e, reg); if (e->k == VJMP) - luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ + luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ if (hasjumps(e)) { int final; /* position after whole expression */ int p_f = NO_JUMP; /* position of an eventual LOAD false */ @@ -406,7 +484,7 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { patchlistaux(fs, e->t, final, reg, p_t); } e->f = e->t = NO_JUMP; - e->u.s.info = reg; + e->u.info = reg; e->k = VNONRELOC; } @@ -422,14 +500,20 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { int luaK_exp2anyreg (FuncState *fs, expdesc *e) { luaK_dischargevars(fs, e); if (e->k == VNONRELOC) { - if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ - if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ - exp2reg(fs, e, e->u.s.info); /* put value on it */ - return e->u.s.info; + if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ + if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.info); /* put value on it */ + return e->u.info; } } luaK_exp2nextreg(fs, e); /* default */ - return e->u.s.info; + return e->u.info; +} + + +void luaK_exp2anyregup (FuncState *fs, expdesc *e) { + if (e->k != VUPVAL || hasjumps(e)) + luaK_exp2anyreg(fs, e); } @@ -444,22 +528,24 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { int luaK_exp2RK (FuncState *fs, expdesc *e) { luaK_exp2val(fs, e); switch (e->k) { - case VKNUM: case VTRUE: case VFALSE: case VNIL: { - if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ - e->u.s.info = (e->k == VNIL) ? nilK(fs) : - (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : - boolK(fs, (e->k == VTRUE)); + if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ + e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); e->k = VK; - return RKASK(e->u.s.info); + return RKASK(e->u.info); } else break; } + case VKNUM: { + e->u.info = luaK_numberK(fs, e->u.nval); + e->k = VK; + /* go through */ + } case VK: { - if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ - return RKASK(e->u.s.info); + if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ + return RKASK(e->u.info); else break; } default: break; @@ -473,22 +559,18 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { switch (var->k) { case VLOCAL: { freeexp(fs, ex); - exp2reg(fs, ex, var->u.s.info); + exp2reg(fs, ex, var->u.info); return; } case VUPVAL: { int e = luaK_exp2anyreg(fs, ex); - luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); - break; - } - case VGLOBAL: { - int e = luaK_exp2anyreg(fs, ex); - luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); break; } case VINDEXED: { + OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; int e = luaK_exp2RK(fs, ex); - luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); + luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); break; } default: { @@ -501,20 +583,20 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { - int func; + int ereg; luaK_exp2anyreg(fs, e); + ereg = e->u.info; /* register where 'e' was placed */ freeexp(fs, e); - func = fs->freereg; - luaK_reserveregs(fs, 2); - luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); - freeexp(fs, key); - e->u.s.info = func; + e->u.info = fs->freereg; /* base register for op_self */ e->k = VNONRELOC; + luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ + luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); + freeexp(fs, key); } static void invertjump (FuncState *fs, expdesc *e) { - Instruction *pc = getjumpcontrol(fs, e->u.s.info); + Instruction *pc = getjumpcontrol(fs, e->u.info); lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && GET_OPCODE(*pc) != OP_TEST); SETARG_A(*pc, !(GETARG_A(*pc))); @@ -532,7 +614,7 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) { } discharge2anyreg(fs, e); freeexp(fs, e); - return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); } @@ -540,17 +622,13 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { - case VK: case VKNUM: case VTRUE: { - pc = NO_JUMP; /* always true; do nothing */ - break; - } - case VFALSE: { - pc = luaK_jump(fs); /* always jump */ - break; - } case VJMP: { invertjump(fs, e); - pc = e->u.s.info; + pc = e->u.info; + break; + } + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ break; } default: { @@ -564,22 +642,18 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { } -static void luaK_goiffalse (FuncState *fs, expdesc *e) { +void luaK_goiffalse (FuncState *fs, expdesc *e) { int pc; /* pc of last jump */ luaK_dischargevars(fs, e); switch (e->k) { + case VJMP: { + pc = e->u.info; + break; + } case VNIL: case VFALSE: { pc = NO_JUMP; /* always false; do nothing */ break; } - case VTRUE: { - pc = luaK_jump(fs); /* always jump */ - break; - } - case VJMP: { - pc = e->u.s.info; - break; - } default: { pc = jumponcond(fs, e, 1); break; @@ -610,7 +684,7 @@ static void codenot (FuncState *fs, expdesc *e) { case VNONRELOC: { discharge2anyreg(fs, e); freeexp(fs, e); - e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); + e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); e->k = VRELOCABLE; break; } @@ -627,38 +701,28 @@ static void codenot (FuncState *fs, expdesc *e) { void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { - t->u.s.aux = luaK_exp2RK(fs, k); + lua_assert(!hasjumps(t)); + t->u.ind.t = t->u.info; + t->u.ind.idx = luaK_exp2RK(fs, k); + t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL + : check_exp(vkisinreg(t->k), VLOCAL); t->k = VINDEXED; } static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { - lua_Number v1, v2, r; + lua_Number r; if (!isnumeral(e1) || !isnumeral(e2)) return 0; - v1 = e1->u.nval; - v2 = e2->u.nval; - switch (op) { - case OP_ADD: r = luai_numadd(v1, v2); break; - case OP_SUB: r = luai_numsub(v1, v2); break; - case OP_MUL: r = luai_nummul(v1, v2); break; - case OP_DIV: - if (v2 == 0) return 0; /* do not attempt to divide by 0 */ - r = luai_numdiv(v1, v2); break; - case OP_MOD: - if (v2 == 0) return 0; /* do not attempt to divide by 0 */ - r = luai_nummod(v1, v2); break; - case OP_POW: r = luai_numpow(v1, v2); break; - case OP_UNM: r = luai_numunm(v1); break; - case OP_LEN: return 0; /* no constant folding for 'len' */ - default: lua_assert(0); r = 0; break; - } - if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ + if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) + return 0; /* do not attempt to divide by 0 */ + r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); e1->u.nval = r; return 1; } -static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { +static void codearith (FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int line) { if (constfolding(op, e1, e2)) return; else { @@ -672,8 +736,9 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { freeexp(fs, e2); freeexp(fs, e1); } - e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); e1->k = VRELOCABLE; + luaK_fixline(fs, line); } } @@ -689,25 +754,28 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ cond = 1; } - e1->u.s.info = condjump(fs, op, cond, o1, o2); + e1->u.info = condjump(fs, op, cond, o1, o2); e1->k = VJMP; } -void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { expdesc e2; e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; switch (op) { case OPR_MINUS: { - if (!isnumeral(e)) - luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ - codearith(fs, OP_UNM, e, &e2); + if (isnumeral(e)) /* minus constant? */ + e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ + else { + luaK_exp2anyreg(fs, e); + codearith(fs, OP_UNM, e, &e2, line); + } break; } case OPR_NOT: codenot(fs, e); break; case OPR_LEN: { luaK_exp2anyreg(fs, e); /* cannot operate on constants */ - codearith(fs, OP_LEN, e, &e2); + codearith(fs, OP_LEN, e, &e2, line); break; } default: lua_assert(0); @@ -742,7 +810,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { } -void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { +void luaK_posfix (FuncState *fs, BinOpr op, + expdesc *e1, expdesc *e2, int line) { switch (op) { case OPR_AND: { lua_assert(e1->t == NO_JUMP); /* list must be closed */ @@ -761,29 +830,30 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { case OPR_CONCAT: { luaK_exp2val(fs, e2); if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { - lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); + lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1); freeexp(fs, e1); - SETARG_B(getcode(fs, e2), e1->u.s.info); - e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; + SETARG_B(getcode(fs, e2), e1->u.info); + e1->k = VRELOCABLE; e1->u.info = e2->u.info; } else { luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ - codearith(fs, OP_CONCAT, e1, e2); + codearith(fs, OP_CONCAT, e1, e2, line); } break; } - case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; - case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; - case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; - case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; - case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; - case OPR_POW: codearith(fs, OP_POW, e1, e2); break; - case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; - case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; - case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; - case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; - case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; - case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); + break; + } + case OPR_EQ: case OPR_LT: case OPR_LE: { + codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2); + break; + } + case OPR_NE: case OPR_GT: case OPR_GE: { + codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2); + break; + } default: lua_assert(0); } } @@ -794,46 +864,18 @@ void luaK_fixline (FuncState *fs, int line) { } -static int luaK_code (FuncState *fs, Instruction i, int line) { - Proto *f = fs->f; - dischargejpc(fs); /* `pc' will change */ - /* put new instruction in code array */ - luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, - MAX_INT, "code size overflow"); - f->code[fs->pc] = i; - /* save corresponding line information */ - luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, - MAX_INT, "code size overflow"); - f->lineinfo[fs->pc] = line; - return fs->pc++; -} - - -int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { - lua_assert(getOpMode(o) == iABC); - lua_assert(getBMode(o) != OpArgN || b == 0); - lua_assert(getCMode(o) != OpArgN || c == 0); - return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); -} - - -int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { - lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); - lua_assert(getCMode(o) == OpArgN); - return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); -} - - void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; int b = (tostore == LUA_MULTRET) ? 0 : tostore; lua_assert(tostore != 0); if (c <= MAXARG_C) luaK_codeABC(fs, OP_SETLIST, base, b, c); - else { + else if (c <= MAXARG_Ax) { luaK_codeABC(fs, OP_SETLIST, base, b, 0); - luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + codeextraarg(fs, c); } + else + luaX_syntaxerror(fs->ls, "constructor too long"); fs->freereg = base + 1; /* free registers with list values */ } diff --git a/src/mod/languages/mod_lua/lua/lcode.h b/src/mod/languages/mod_lua/lua/lcode.h index b941c60721..5a1fa9feac 100644 --- a/src/mod/languages/mod_lua/lua/lcode.h +++ b/src/mod/languages/mod_lua/lua/lcode.h @@ -1,5 +1,5 @@ /* -** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lcode.h,v 1.58 2011/08/30 16:26:41 roberto Exp $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -21,13 +21,13 @@ /* -** grep "ORDER OPR" if you change these enums +** grep "ORDER OPR" if you change these enums (ORDER OP) */ typedef enum BinOpr { OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, OPR_CONCAT, - OPR_NE, OPR_EQ, - OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_EQ, OPR_LT, OPR_LE, + OPR_NE, OPR_GT, OPR_GE, OPR_AND, OPR_OR, OPR_NOBINOPR } BinOpr; @@ -36,14 +36,17 @@ typedef enum BinOpr { typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; -#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) +#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) +#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) + LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); LUAI_FUNC void luaK_fixline (FuncState *fs, int line); LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); @@ -52,12 +55,14 @@ LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); @@ -65,11 +70,13 @@ LUAI_FUNC int luaK_jump (FuncState *fs); LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); LUAI_FUNC int luaK_getlabel (FuncState *fs); -LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); -LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); diff --git a/src/mod/languages/mod_lua/lua/ldblib.c b/src/mod/languages/mod_lua/lua/ldblib.c index 67de1222a9..c022694573 100644 --- a/src/mod/languages/mod_lua/lua/ldblib.c +++ b/src/mod/languages/mod_lua/lua/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ +** $Id: ldblib.c,v 1.132 2012/01/19 20:14:44 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -18,6 +18,9 @@ #include "lualib.h" +#define HOOKKEY "_HKEY" + + static int db_getregistry (lua_State *L) { lua_pushvalue(L, LUA_REGISTRYINDEX); @@ -39,23 +42,28 @@ static int db_setmetatable (lua_State *L) { luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, "nil or table expected"); lua_settop(L, 2); - lua_pushboolean(L, lua_setmetatable(L, 1)); + lua_setmetatable(L, 1); + return 1; /* return 1st argument */ +} + + +static int db_getuservalue (lua_State *L) { + if (lua_type(L, 1) != LUA_TUSERDATA) + lua_pushnil(L); + else + lua_getuservalue(L, 1); return 1; } -static int db_getfenv (lua_State *L) { - lua_getfenv(L, 1); - return 1; -} - - -static int db_setfenv (lua_State *L) { - luaL_checktype(L, 2, LUA_TTABLE); +static int db_setuservalue (lua_State *L) { + if (lua_type(L, 1) == LUA_TLIGHTUSERDATA) + luaL_argerror(L, 1, "full userdata expected, got light userdata"); + luaL_checktype(L, 1, LUA_TUSERDATA); + if (!lua_isnoneornil(L, 2)) + luaL_checktype(L, 2, LUA_TTABLE); lua_settop(L, 2); - if (lua_setfenv(L, 1) == 0) - luaL_error(L, LUA_QL("setfenv") - " cannot change environment of given object"); + lua_setuservalue(L, 1); return 1; } @@ -72,6 +80,12 @@ static void settabsi (lua_State *L, const char *i, int v) { } +static void settabsb (lua_State *L, const char *i, int v) { + lua_pushboolean(L, v); + lua_setfield(L, -2, i); +} + + static lua_State *getthread (lua_State *L, int *arg) { if (lua_isthread(L, 1)) { *arg = 1; @@ -99,7 +113,7 @@ static int db_getinfo (lua_State *L) { lua_Debug ar; int arg; lua_State *L1 = getthread(L, &arg); - const char *options = luaL_optstring(L, arg+2, "flnSu"); + const char *options = luaL_optstring(L, arg+2, "flnStu"); if (lua_isnumber(L, arg+1)) { if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { lua_pushnil(L); /* level out of range */ @@ -126,38 +140,51 @@ static int db_getinfo (lua_State *L) { } if (strchr(options, 'l')) settabsi(L, "currentline", ar.currentline); - if (strchr(options, 'u')) + if (strchr(options, 'u')) { settabsi(L, "nups", ar.nups); + settabsi(L, "nparams", ar.nparams); + settabsb(L, "isvararg", ar.isvararg); + } if (strchr(options, 'n')) { settabss(L, "name", ar.name); settabss(L, "namewhat", ar.namewhat); } + if (strchr(options, 't')) + settabsb(L, "istailcall", ar.istailcall); if (strchr(options, 'L')) treatstackoption(L, L1, "activelines"); if (strchr(options, 'f')) treatstackoption(L, L1, "func"); return 1; /* return table */ } - + static int db_getlocal (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); lua_Debug ar; const char *name; - if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ - return luaL_argerror(L, arg+1, "level out of range"); - name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); - if (name) { - lua_xmove(L1, L, 1); - lua_pushstring(L, name); - lua_pushvalue(L, -2); - return 2; - } - else { - lua_pushnil(L); + int nvar = luaL_checkint(L, arg+2); /* local-variable index */ + if (lua_isfunction(L, arg + 1)) { /* function argument? */ + lua_pushvalue(L, arg + 1); /* push function */ + lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ return 1; } + else { /* stack-level argument */ + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, nvar); + if (name) { + lua_xmove(L1, L, 1); /* push local value */ + lua_pushstring(L, name); /* push name */ + lua_pushvalue(L, -2); /* re-order */ + return 2; + } + else { + lua_pushnil(L); /* no name (nor value) */ + return 1; + } + } } @@ -179,7 +206,6 @@ static int auxupvalue (lua_State *L, int get) { const char *name; int n = luaL_checkint(L, 2); luaL_checktype(L, 1, LUA_TFUNCTION); - if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); if (name == NULL) return 0; lua_pushstring(L, name); @@ -199,16 +225,42 @@ static int db_setupvalue (lua_State *L) { } +static int checkupval (lua_State *L, int argf, int argnup) { + lua_Debug ar; + int nup = luaL_checkint(L, argnup); + luaL_checktype(L, argf, LUA_TFUNCTION); + lua_pushvalue(L, argf); + lua_getinfo(L, ">u", &ar); + luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index"); + return nup; +} -static const char KEY_HOOK = 'h'; + +static int db_upvalueid (lua_State *L) { + int n = checkupval(L, 1, 2); + lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); + return 1; +} + + +static int db_upvaluejoin (lua_State *L) { + int n1 = checkupval(L, 1, 2); + int n2 = checkupval(L, 3, 4); + luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); + luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); + lua_upvaluejoin(L, 1, n1, 3, n2); + return 0; +} + + +#define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY) static void hookf (lua_State *L, lua_Debug *ar) { static const char *const hooknames[] = - {"call", "return", "line", "count", "tail return"}; - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_pushlightuserdata(L, L); + {"call", "return", "line", "count", "tail call"}; + gethooktable(L); + lua_pushthread(L); lua_rawget(L, -2); if (lua_isfunction(L, -1)) { lua_pushstring(L, hooknames[(int)ar->event]); @@ -241,19 +293,6 @@ static char *unmakemask (int mask, char *smask) { } -static void gethooktable (lua_State *L) { - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_rawget(L, LUA_REGISTRYINDEX); - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - lua_createtable(L, 0, 1); - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } -} - - static int db_sethook (lua_State *L) { int arg, mask, count; lua_Hook func; @@ -268,11 +307,15 @@ static int db_sethook (lua_State *L) { count = luaL_optint(L, arg+3, 0); func = hookf; mask = makemask(smask, count); } - gethooktable(L); - lua_pushlightuserdata(L, L1); + if (gethooktable(L) == 0) { /* creating hook table? */ + lua_pushstring(L, "k"); + lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ + } + lua_pushthread(L1); lua_xmove(L1, L, 1); lua_pushvalue(L, arg+1); lua_rawset(L, -3); /* set new hook */ - lua_pop(L, 1); /* remove hook table */ lua_sethook(L1, func, mask, count); /* set hooks */ return 0; } @@ -288,7 +331,7 @@ static int db_gethook (lua_State *L) { lua_pushliteral(L, "external hook"); else { gethooktable(L); - lua_pushlightuserdata(L, L1); + lua_pushthread(L1); lua_xmove(L1, L, 1); lua_rawget(L, -2); /* get hook */ lua_remove(L, -2); /* remove hook table */ } @@ -301,97 +344,55 @@ static int db_gethook (lua_State *L) { static int db_debug (lua_State *L) { for (;;) { char buffer[250]; - fputs("lua_debug> ", stderr); + luai_writestringerror("%s", "lua_debug> "); if (fgets(buffer, sizeof(buffer), stdin) == 0 || strcmp(buffer, "cont\n") == 0) return 0; if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || - lua_pcall(L, 0, 0, 0)) { - fputs(lua_tostring(L, -1), stderr); - fputs("\n", stderr); - } + lua_pcall(L, 0, 0, 0)) + luai_writestringerror("%s\n", lua_tostring(L, -1)); lua_settop(L, 0); /* remove eventual returns */ } } -#define LEVELS1 12 /* size of the first part of the stack */ -#define LEVELS2 10 /* size of the second part of the stack */ - -static int db_errorfb (lua_State *L) { - int level; - int firstpart = 1; /* still before eventual `...' */ +static int db_traceback (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - if (lua_isnumber(L, arg+2)) { - level = (int)lua_tointeger(L, arg+2); - lua_pop(L, 1); + const char *msg = lua_tostring(L, arg + 1); + if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ + lua_pushvalue(L, arg + 1); /* return it untouched */ + else { + int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0); + luaL_traceback(L, L1, msg, level); } - else - level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ - if (lua_gettop(L) == arg) - lua_pushliteral(L, ""); - else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ - else lua_pushliteral(L, "\n"); - lua_pushliteral(L, "stack traceback:"); - while (lua_getstack(L1, level++, &ar)) { - if (level > LEVELS1 && firstpart) { - /* no more than `LEVELS2' more levels? */ - if (!lua_getstack(L1, level+LEVELS2, &ar)) - level--; /* keep going */ - else { - lua_pushliteral(L, "\n\t..."); /* too many levels */ - while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ - level++; - } - firstpart = 0; - continue; - } - lua_pushliteral(L, "\n\t"); - lua_getinfo(L1, "Snl", &ar); - lua_pushfstring(L, "%s:", ar.short_src); - if (ar.currentline > 0) - lua_pushfstring(L, "%d:", ar.currentline); - if (*ar.namewhat != '\0') /* is there a name? */ - lua_pushfstring(L, " in function " LUA_QS, ar.name); - else { - if (*ar.what == 'm') /* main? */ - lua_pushfstring(L, " in main chunk"); - else if (*ar.what == 'C' || *ar.what == 't') - lua_pushliteral(L, " ?"); /* C function or tail call */ - else - lua_pushfstring(L, " in function <%s:%d>", - ar.short_src, ar.linedefined); - } - lua_concat(L, lua_gettop(L) - arg); - } - lua_concat(L, lua_gettop(L) - arg); return 1; } static const luaL_Reg dblib[] = { {"debug", db_debug}, - {"getfenv", db_getfenv}, + {"getuservalue", db_getuservalue}, {"gethook", db_gethook}, {"getinfo", db_getinfo}, {"getlocal", db_getlocal}, {"getregistry", db_getregistry}, {"getmetatable", db_getmetatable}, {"getupvalue", db_getupvalue}, - {"setfenv", db_setfenv}, + {"upvaluejoin", db_upvaluejoin}, + {"upvalueid", db_upvalueid}, + {"setuservalue", db_setuservalue}, {"sethook", db_sethook}, {"setlocal", db_setlocal}, {"setmetatable", db_setmetatable}, {"setupvalue", db_setupvalue}, - {"traceback", db_errorfb}, + {"traceback", db_traceback}, {NULL, NULL} }; -LUALIB_API int luaopen_debug (lua_State *L) { - luaL_register(L, LUA_DBLIBNAME, dblib); +LUAMOD_API int luaopen_debug (lua_State *L) { + luaL_newlib(L, dblib); return 1; } diff --git a/src/mod/languages/mod_lua/lua/ldebug.c b/src/mod/languages/mod_lua/lua/ldebug.c index 50ad3d3803..7e04f9d09f 100644 --- a/src/mod/languages/mod_lua/lua/ldebug.c +++ b/src/mod/languages/mod_lua/lua/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ +** $Id: ldebug.c,v 2.90 2012/08/16 17:34:28 roberto Exp $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -30,23 +30,20 @@ +#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) + + static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); -static int currentpc (lua_State *L, CallInfo *ci) { - if (!isLua(ci)) return -1; /* function is not a Lua function? */ - if (ci == L->ci) - ci->savedpc = L->savedpc; - return pcRel(ci->savedpc, ci_func(ci)->l.p); +static int currentpc (CallInfo *ci) { + lua_assert(isLua(ci)); + return pcRel(ci->u.l.savedpc, ci_func(ci)->p); } -static int currentline (lua_State *L, CallInfo *ci) { - int pc = currentpc(L, ci); - if (pc < 0) - return -1; /* only active lua functions have current-line information */ - else - return getline(ci_func(ci)->l.p, pc); +static int currentline (CallInfo *ci) { + return getfuncline(ci_func(ci)->p, currentpc(ci)); } @@ -58,6 +55,8 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { mask = 0; func = NULL; } + if (isLua(L->ci)) + L->oldpc = L->ci->u.l.savedpc; L->hook = func; L->basehookcount = count; resethookcount(L); @@ -84,19 +83,13 @@ LUA_API int lua_gethookcount (lua_State *L) { LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { int status; CallInfo *ci; + if (level < 0) return 0; /* invalid (negative) level */ lua_lock(L); - for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { + for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) level--; - if (f_isLua(ci)) /* Lua function? */ - level -= ci->tailcalls; /* skip lost tail calls */ - } - if (level == 0 && ci > L->base_ci) { /* level found? */ + if (level == 0 && ci != &L->base_ci) { /* level found? */ status = 1; - ar->i_ci = cast_int(ci - L->base_ci); - } - else if (level < 0) { /* level is of a lost tail call? */ - status = 1; - ar->i_ci = 0; + ar->i_ci = ci; } else status = 0; /* no such level */ lua_unlock(L); @@ -104,43 +97,78 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { } -static Proto *getluaproto (CallInfo *ci) { - return (isLua(ci) ? ci_func(ci)->l.p : NULL); +static const char *upvalname (Proto *p, int uv) { + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); + if (s == NULL) return "?"; + else return getstr(s); } -static const char *findlocal (lua_State *L, CallInfo *ci, int n) { - const char *name; - Proto *fp = getluaproto(ci); - if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) - return name; /* is a local variable in a Lua function */ +static const char *findvararg (CallInfo *ci, int n, StkId *pos) { + int nparams = clLvalue(ci->func)->p->numparams; + if (n >= ci->u.l.base - ci->func - nparams) + return NULL; /* no such vararg */ else { - StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; - if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ - return "(*temporary)"; - else - return NULL; + *pos = ci->func + nparams + n; + return "(*vararg)"; /* generic name for any vararg */ } } +static const char *findlocal (lua_State *L, CallInfo *ci, int n, + StkId *pos) { + const char *name = NULL; + StkId base; + if (isLua(ci)) { + if (n < 0) /* access to vararg values? */ + return findvararg(ci, -n, pos); + else { + base = ci->u.l.base; + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } + } + else + base = ci->func + 1; + if (name == NULL) { /* no 'standard' name? */ + StkId limit = (ci == L->ci) ? L->top : ci->next->func; + if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + name = "(*temporary)"; /* generic name for any valid slot */ + else + return NULL; /* no name */ + } + *pos = base + (n - 1); + return name; +} + + LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { - CallInfo *ci = L->base_ci + ar->i_ci; - const char *name = findlocal(L, ci, n); + const char *name; lua_lock(L); - if (name) - luaA_pushobject(L, ci->base + (n - 1)); + if (ar == NULL) { /* information about non-active function? */ + if (!isLfunction(L->top - 1)) /* not a Lua function? */ + name = NULL; + else /* consider live variables at function start (parameters) */ + name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); + } + else { /* active function; get information through 'ar' */ + StkId pos = 0; /* to avoid warnings */ + name = findlocal(L, ar->i_ci, n, &pos); + if (name) { + setobj2s(L, L->top, pos); + api_incr_top(L); + } + } lua_unlock(L); return name; } LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { - CallInfo *ci = L->base_ci + ar->i_ci; - const char *name = findlocal(L, ci, n); + StkId pos = 0; /* to avoid warnings */ + const char *name = findlocal(L, ar->i_ci, n, &pos); lua_lock(L); if (name) - setobjs2s(L, ci->base + (n - 1), L->top - 1); + setobjs2s(L, pos, L->top - 1); L->top--; /* pop value */ lua_unlock(L); return name; @@ -148,55 +176,45 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { static void funcinfo (lua_Debug *ar, Closure *cl) { - if (cl->c.isC) { + if (noLuaClosure(cl)) { ar->source = "=[C]"; ar->linedefined = -1; ar->lastlinedefined = -1; ar->what = "C"; } else { - ar->source = getstr(cl->l.p->source); - ar->linedefined = cl->l.p->linedefined; - ar->lastlinedefined = cl->l.p->lastlinedefined; + Proto *p = cl->l.p; + ar->source = p->source ? getstr(p->source) : "=?"; + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; ar->what = (ar->linedefined == 0) ? "main" : "Lua"; } luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); } -static void info_tailcall (lua_Debug *ar) { - ar->name = ar->namewhat = ""; - ar->what = "tail"; - ar->lastlinedefined = ar->linedefined = ar->currentline = -1; - ar->source = "=(tail call)"; - luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); - ar->nups = 0; -} - - static void collectvalidlines (lua_State *L, Closure *f) { - if (f == NULL || f->c.isC) { + if (noLuaClosure(f)) { setnilvalue(L->top); + api_incr_top(L); } else { - Table *t = luaH_new(L, 0, 0); - int *lineinfo = f->l.p->lineinfo; int i; - for (i=0; il.p->sizelineinfo; i++) - setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); - sethvalue(L, L->top, t); + TValue v; + int *lineinfo = f->l.p->lineinfo; + Table *t = luaH_new(L); /* new table to store active lines */ + sethvalue(L, L->top, t); /* push it on stack */ + api_incr_top(L); + setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ + for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ + luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ } - incr_top(L); } static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, - Closure *f, CallInfo *ci) { + Closure *f, CallInfo *ci) { int status = 1; - if (f == NULL) { - info_tailcall(ar); - return status; - } for (; *what; what++) { switch (*what) { case 'S': { @@ -204,15 +222,31 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, break; } case 'l': { - ar->currentline = (ci) ? currentline(L, ci) : -1; + ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; break; } case 'u': { - ar->nups = f->c.nupvalues; + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; + if (noLuaClosure(f)) { + ar->isvararg = 1; + ar->nparams = 0; + } + else { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 't': { + ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; break; } case 'n': { - ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; + /* calling function is a known Lua function? */ + if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) + ar->namewhat = getfuncname(L, ci->previous, &ar->name); + else + ar->namewhat = NULL; if (ar->namewhat == NULL) { ar->namewhat = ""; /* not found */ ar->name = NULL; @@ -231,29 +265,30 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { int status; - Closure *f = NULL; - CallInfo *ci = NULL; + Closure *cl; + CallInfo *ci; + StkId func; lua_lock(L); if (*what == '>') { - StkId func = L->top - 1; - luai_apicheck(L, ttisfunction(func)); + ci = NULL; + func = L->top - 1; + api_check(L, ttisfunction(func), "function expected"); what++; /* skip the '>' */ - f = clvalue(func); L->top--; /* pop function */ } - else if (ar->i_ci != 0) { /* no tail call? */ - ci = L->base_ci + ar->i_ci; + else { + ci = ar->i_ci; + func = ci->func; lua_assert(ttisfunction(ci->func)); - f = clvalue(ci->func); } - status = auxgetinfo(L, what, ar, f, ci); + cl = ttisclosure(func) ? clvalue(func) : NULL; + status = auxgetinfo(L, what, ar, cl, ci); if (strchr(what, 'f')) { - if (f == NULL) setnilvalue(L->top); - else setclvalue(L, L->top, f); - incr_top(L); + setobjs2s(L, L->top, func); + api_incr_top(L); } if (strchr(what, 'L')) - collectvalidlines(L, f); + collectvalidlines(L, cl); lua_unlock(L); return status; } @@ -261,315 +296,218 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { /* ** {====================================================== -** Symbolic Execution and code checker +** Symbolic Execution ** ======================================================= */ -#define check(x) if (!(x)) return 0; - -#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) - -#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) +static const char *getobjname (Proto *p, int lastpc, int reg, + const char **name); - -static int precheck (const Proto *pt) { - check(pt->maxstacksize <= MAXSTACK); - check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); - check(!(pt->is_vararg & VARARG_NEEDSARG) || - (pt->is_vararg & VARARG_HASARG)); - check(pt->sizeupvalues <= pt->nups); - check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); - check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); - return 1; -} - - -#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) - -int luaG_checkopenop (Instruction i) { - switch (GET_OPCODE(i)) { - case OP_CALL: - case OP_TAILCALL: - case OP_RETURN: - case OP_SETLIST: { - check(GETARG_B(i) == 0); - return 1; +/* +** find a "name" for the RK value 'c' +*/ +static void kname (Proto *p, int pc, int c, const char **name) { + if (ISK(c)) { /* is 'c' a constant? */ + TValue *kvalue = &p->k[INDEXK(c)]; + if (ttisstring(kvalue)) { /* literal constant? */ + *name = svalue(kvalue); /* it is its own name */ + return; } - default: return 0; /* invalid instruction after an open call */ + /* else no reasonable name found */ } + else { /* 'c' is a register */ + const char *what = getobjname(p, pc, c, name); /* search for 'c' */ + if (what && *what == 'c') { /* found a constant name? */ + return; /* 'name' already filled */ + } + /* else no reasonable name found */ + } + *name = "?"; /* no reasonable name found */ } -static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { - switch (mode) { - case OpArgN: check(r == 0); break; - case OpArgU: break; - case OpArgR: checkreg(pt, r); break; - case OpArgK: - check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); - break; - } - return 1; -} - - -static Instruction symbexec (const Proto *pt, int lastpc, int reg) { +/* +** try to find last instruction before 'lastpc' that modified register 'reg' +*/ +static int findsetreg (Proto *p, int lastpc, int reg) { int pc; - int last; /* stores position of last instruction that changed `reg' */ - last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ - check(precheck(pt)); + int setreg = -1; /* keep last instruction that changed 'reg' */ for (pc = 0; pc < lastpc; pc++) { - Instruction i = pt->code[pc]; + Instruction i = p->code[pc]; OpCode op = GET_OPCODE(i); int a = GETARG_A(i); - int b = 0; - int c = 0; - check(op < NUM_OPCODES); - checkreg(pt, a); - switch (getOpMode(op)) { - case iABC: { - b = GETARG_B(i); - c = GETARG_C(i); - check(checkArgMode(pt, b, getBMode(op))); - check(checkArgMode(pt, c, getCMode(op))); - break; - } - case iABx: { - b = GETARG_Bx(i); - if (getBMode(op) == OpArgK) check(b < pt->sizek); - break; - } - case iAsBx: { - b = GETARG_sBx(i); - if (getBMode(op) == OpArgR) { - int dest = pc+1+b; - check(0 <= dest && dest < pt->sizecode); - if (dest > 0) { - int j; - /* check that it does not jump to a setlist count; this - is tricky, because the count from a previous setlist may - have the same value of an invalid setlist; so, we must - go all the way back to the first of them (if any) */ - for (j = 0; j < dest; j++) { - Instruction d = pt->code[dest-1-j]; - if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; - } - /* if 'j' is even, previous value is not a setlist (even if - it looks like one) */ - check((j&1) == 0); - } - } - break; - } - } - if (testAMode(op)) { - if (a == reg) last = pc; /* change register `a' */ - } - if (testTMode(op)) { - check(pc+2 < pt->sizecode); /* check skip */ - check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); - } switch (op) { - case OP_LOADBOOL: { - if (c == 1) { /* does it jump? */ - check(pc+2 < pt->sizecode); /* check its jump */ - check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || - GETARG_C(pt->code[pc+1]) != 0); - } - break; - } case OP_LOADNIL: { - if (a <= reg && reg <= b) - last = pc; /* set registers from `a' to `b' */ + int b = GETARG_B(i); + if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ + setreg = pc; break; } - case OP_GETUPVAL: - case OP_SETUPVAL: { - check(b < pt->nups); - break; - } - case OP_GETGLOBAL: - case OP_SETGLOBAL: { - check(ttisstring(&pt->k[b])); - break; - } - case OP_SELF: { - checkreg(pt, a+1); - if (reg == a+1) last = pc; - break; - } - case OP_CONCAT: { - check(b < c); /* at least two operands */ - break; - } - case OP_TFORLOOP: { - check(c >= 1); /* at least one result (control variable) */ - checkreg(pt, a+2+c); /* space for results */ - if (reg >= a+2) last = pc; /* affect all regs above its base */ - break; - } - case OP_FORLOOP: - case OP_FORPREP: - checkreg(pt, a+3); - /* go through */ - case OP_JMP: { - int dest = pc+1+b; - /* not full check and jump is forward and do not skip `lastpc'? */ - if (reg != NO_REG && pc < dest && dest <= lastpc) - pc += b; /* do the jump */ + case OP_TFORCALL: { + if (reg >= a + 2) setreg = pc; /* affect all regs above its base */ break; } case OP_CALL: case OP_TAILCALL: { - if (b != 0) { - checkreg(pt, a+b-1); - } - c--; /* c = num. returns */ - if (c == LUA_MULTRET) { - check(checkopenop(pt, pc)); - } - else if (c != 0) - checkreg(pt, a+c-1); - if (reg >= a) last = pc; /* affect all registers above base */ + if (reg >= a) setreg = pc; /* affect all registers above base */ break; } - case OP_RETURN: { - b--; /* b = num. returns */ - if (b > 0) checkreg(pt, a+b-1); + case OP_JMP: { + int b = GETARG_sBx(i); + int dest = pc + 1 + b; + /* jump is forward and do not skip `lastpc'? */ + if (pc < dest && dest <= lastpc) + pc += b; /* do the jump */ break; } - case OP_SETLIST: { - if (b > 0) checkreg(pt, a + b); - if (c == 0) { - pc++; - check(pc < pt->sizecode - 1); - } + case OP_TEST: { + if (reg == a) setreg = pc; /* jumped code can change 'a' */ break; } - case OP_CLOSURE: { - int nup, j; - check(b < pt->sizep); - nup = pt->p[b]->nups; - check(pc + nup < pt->sizecode); - for (j = 1; j <= nup; j++) { - OpCode op1 = GET_OPCODE(pt->code[pc + j]); - check(op1 == OP_GETUPVAL || op1 == OP_MOVE); - } - if (reg != NO_REG) /* tracing? */ - pc += nup; /* do not 'execute' these pseudo-instructions */ + default: + if (testAMode(op) && reg == a) /* any instruction that set A */ + setreg = pc; break; - } - case OP_VARARG: { - check((pt->is_vararg & VARARG_ISVARARG) && - !(pt->is_vararg & VARARG_NEEDSARG)); - b--; - if (b == LUA_MULTRET) check(checkopenop(pt, pc)); - checkreg(pt, a+b-1); - break; - } - default: break; } } - return pt->code[last]; -} - -#undef check -#undef checkjump -#undef checkreg - -/* }====================================================== */ - - -int luaG_checkcode (const Proto *pt) { - return (symbexec(pt, pt->sizecode, NO_REG) != 0); + return setreg; } -static const char *kname (Proto *p, int c) { - if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) - return svalue(&p->k[INDEXK(c)]); - else - return "?"; -} - - -static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, +static const char *getobjname (Proto *p, int lastpc, int reg, const char **name) { - if (isLua(ci)) { /* a Lua function? */ - Proto *p = ci_func(ci)->l.p; - int pc = currentpc(L, ci); - Instruction i; - *name = luaF_getlocalname(p, stackpos+1, pc); - if (*name) /* is a local? */ - return "local"; - i = symbexec(p, pc, stackpos); /* try symbolic execution */ - lua_assert(pc != -1); - switch (GET_OPCODE(i)) { - case OP_GETGLOBAL: { - int g = GETARG_Bx(i); /* global index */ - lua_assert(ttisstring(&p->k[g])); - *name = svalue(&p->k[g]); - return "global"; - } + int pc; + *name = luaF_getlocalname(p, reg + 1, lastpc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ + pc = findsetreg(p, lastpc, reg); + if (pc != -1) { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + switch (op) { case OP_MOVE: { - int a = GETARG_A(i); - int b = GETARG_B(i); /* move from `b' to `a' */ - if (b < a) - return getobjname(L, ci, b, name); /* get name for `b' */ + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) + return getobjname(p, pc, b, name); /* get name for 'b' */ break; } + case OP_GETTABUP: case OP_GETTABLE: { int k = GETARG_C(i); /* key index */ - *name = kname(p, k); - return "field"; + int t = GETARG_B(i); /* table index */ + const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ + ? luaF_getlocalname(p, t + 1, pc) + : upvalname(p, t); + kname(p, pc, k, name); + return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; } case OP_GETUPVAL: { - int u = GETARG_B(i); /* upvalue index */ - *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + *name = upvalname(p, GETARG_B(i)); return "upvalue"; } + case OP_LOADK: + case OP_LOADKX: { + int b = (op == OP_LOADK) ? GETARG_Bx(i) + : GETARG_Ax(p->code[pc + 1]); + if (ttisstring(&p->k[b])) { + *name = svalue(&p->k[b]); + return "constant"; + } + break; + } case OP_SELF: { int k = GETARG_C(i); /* key index */ - *name = kname(p, k); + kname(p, pc, k, name); return "method"; } - default: break; + default: break; /* go through to return NULL */ } } - return NULL; /* no useful name found */ + return NULL; /* could not find reasonable name */ } static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { - Instruction i; - if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) - return NULL; /* calling function is not Lua (or is unknown) */ - ci--; /* calling function */ - i = ci_func(ci)->l.p->code[currentpc(L, ci)]; - if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || - GET_OPCODE(i) == OP_TFORLOOP) - return getobjname(L, ci, GETARG_A(i), name); - else - return NULL; /* no useful name can be found */ + TMS tm; + Proto *p = ci_func(ci)->p; /* calling function */ + int pc = currentpc(ci); /* calling instruction index */ + Instruction i = p->code[pc]; /* calling instruction */ + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: /* get function name */ + return getobjname(p, pc, GETARG_A(i), name); + case OP_TFORCALL: { /* for iterator */ + *name = "for iterator"; + return "for iterator"; + } + /* all other instructions can call only through metamethods */ + case OP_SELF: + case OP_GETTABUP: + case OP_GETTABLE: tm = TM_INDEX; break; + case OP_SETTABUP: + case OP_SETTABLE: tm = TM_NEWINDEX; break; + case OP_EQ: tm = TM_EQ; break; + case OP_ADD: tm = TM_ADD; break; + case OP_SUB: tm = TM_SUB; break; + case OP_MUL: tm = TM_MUL; break; + case OP_DIV: tm = TM_DIV; break; + case OP_MOD: tm = TM_MOD; break; + case OP_POW: tm = TM_POW; break; + case OP_UNM: tm = TM_UNM; break; + case OP_LEN: tm = TM_LEN; break; + case OP_LT: tm = TM_LT; break; + case OP_LE: tm = TM_LE; break; + case OP_CONCAT: tm = TM_CONCAT; break; + default: + return NULL; /* else no useful name can be found */ + } + *name = getstr(G(L)->tmname[tm]); + return "metamethod"; } +/* }====================================================== */ -/* only ANSI way to check whether a pointer points to an array */ + + +/* +** only ANSI way to check whether a pointer points to an array +** (used only for error messages, so efficiency is not a big concern) +*/ static int isinstack (CallInfo *ci, const TValue *o) { StkId p; - for (p = ci->base; p < ci->top; p++) + for (p = ci->u.l.base; p < ci->top; p++) if (o == p) return 1; return 0; } -void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { +static const char *getupvalname (CallInfo *ci, const TValue *o, + const char **name) { + LClosure *c = ci_func(ci); + int i; + for (i = 0; i < c->nupvalues; i++) { + if (c->upvals[i]->v == o) { + *name = upvalname(c->p, i); + return "upvalue"; + } + } + return NULL; +} + + +l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + CallInfo *ci = L->ci; const char *name = NULL; - const char *t = luaT_typenames[ttype(o)]; - const char *kind = (isinstack(L->ci, o)) ? - getobjname(L, L->ci, cast_int(o - L->base), &name) : - NULL; + const char *t = objtypename(o); + const char *kind = NULL; + if (isLua(ci)) { + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ + if (!kind && isinstack(ci, o)) /* no? try a register */ + kind = getobjname(ci_func(ci)->p, currentpc(ci), + cast_int(o - ci->u.l.base), &name); + } if (kind) luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", op, kind, name, t); @@ -578,14 +516,14 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { } -void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { +l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) { if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; - lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + lua_assert(!ttisstring(p1) && !ttisnumber(p2)); luaG_typeerror(L, p1, "concatenate"); } -void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { +l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { TValue temp; if (luaV_tonumber(p1, &temp) == NULL) p2 = p1; /* first operand is wrong */ @@ -593,14 +531,13 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { } -int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { - const char *t1 = luaT_typenames[ttype(p1)]; - const char *t2 = luaT_typenames[ttype(p2)]; - if (t1[2] == t2[2]) +l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = objtypename(p1); + const char *t2 = objtypename(p2); + if (t1 == t2) luaG_runerror(L, "attempt to compare two %s values", t1); else luaG_runerror(L, "attempt to compare %s with %s", t1, t2); - return 0; } @@ -608,27 +545,32 @@ static void addinfo (lua_State *L, const char *msg) { CallInfo *ci = L->ci; if (isLua(ci)) { /* is Lua code? */ char buff[LUA_IDSIZE]; /* add file:line information */ - int line = currentline(L, ci); - luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + int line = currentline(ci); + TString *src = ci_func(ci)->p->source; + if (src) + luaO_chunkid(buff, getstr(src), LUA_IDSIZE); + else { /* no source available; use "?" instead */ + buff[0] = '?'; buff[1] = '\0'; + } luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); } } -void luaG_errormsg (lua_State *L) { +l_noret luaG_errormsg (lua_State *L) { if (L->errfunc != 0) { /* is there an error handling function? */ StkId errfunc = restorestack(L, L->errfunc); if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); setobjs2s(L, L->top, L->top - 1); /* move argument */ setobjs2s(L, L->top - 1, errfunc); /* push function */ - incr_top(L); - luaD_call(L, L->top - 2, 1); /* call it */ + L->top++; + luaD_call(L, L->top - 2, 1, 0); /* call it */ } luaD_throw(L, LUA_ERRRUN); } -void luaG_runerror (lua_State *L, const char *fmt, ...) { +l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { va_list argp; va_start(argp, fmt); addinfo(L, luaO_pushvfstring(L, fmt, argp)); diff --git a/src/mod/languages/mod_lua/lua/ldebug.h b/src/mod/languages/mod_lua/lua/ldebug.h index ba28a97248..fe39556b06 100644 --- a/src/mod/languages/mod_lua/lua/ldebug.h +++ b/src/mod/languages/mod_lua/lua/ldebug.h @@ -1,5 +1,5 @@ /* -** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: ldebug.h,v 2.7 2011/10/07 20:45:19 roberto Exp $ ** Auxiliary functions from Debug Interface module ** See Copyright Notice in lua.h */ @@ -13,21 +13,22 @@ #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) -#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) +#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) #define resethookcount(L) (L->hookcount = L->basehookcount) +/* Active Lua function (given call info) */ +#define ci_func(ci) (clLvalue((ci)->func)) -LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, - const char *opname); -LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); -LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, - const TValue *p2); -LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, - const TValue *p2); -LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); -LUAI_FUNC void luaG_errormsg (lua_State *L); -LUAI_FUNC int luaG_checkcode (const Proto *pt); -LUAI_FUNC int luaG_checkopenop (Instruction i); + +LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC l_noret luaG_errormsg (lua_State *L); #endif diff --git a/src/mod/languages/mod_lua/lua/ldo.c b/src/mod/languages/mod_lua/lua/ldo.c index 8de05f728e..aafa3dca23 100644 --- a/src/mod/languages/mod_lua/lua/ldo.c +++ b/src/mod/languages/mod_lua/lua/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ +** $Id: ldo.c,v 2.108 2012/10/01 14:05:04 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -14,6 +14,7 @@ #include "lua.h" +#include "lapi.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" @@ -39,6 +40,38 @@ ** ======================================================= */ +/* +** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By +** default, Lua handles errors with exceptions when compiling as +** C++ code, with _longjmp/_setjmp when asked to use them, and with +** longjmp/setjmp otherwise. +*/ +#if !defined(LUAI_THROW) + +#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) \ + try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + +#endif + + /* chain list of long jump buffers */ struct lua_longjmp { @@ -48,18 +81,17 @@ struct lua_longjmp { }; -void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { +static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { switch (errcode) { - case LUA_ERRMEM: { - setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); + case LUA_ERRMEM: { /* memory error? */ + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ break; } case LUA_ERRERR: { setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); break; } - case LUA_ERRSYNTAX: - case LUA_ERRRUN: { + default: { setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ break; } @@ -68,55 +100,39 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { } -static void restore_stack_limit (lua_State *L) { - lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); - if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ - int inuse = cast_int(L->ci - L->base_ci); - if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ - luaD_reallocCI(L, LUAI_MAXCALLS); +l_noret luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { /* thread has an error handler? */ + L->errorJmp->status = errcode; /* set status */ + LUAI_THROW(L, L->errorJmp); /* jump to it */ } -} - - -static void resetstack (lua_State *L, int status) { - L->ci = L->base_ci; - L->base = L->ci->base; - luaF_close(L, L->base); /* close eventual pending closures */ - luaD_seterrorobj(L, status, L->base); - L->nCcalls = L->baseCcalls; - L->allowhook = 1; - restore_stack_limit(L); - L->errfunc = 0; - L->errorJmp = NULL; -} - - -void luaD_throw (lua_State *L, int errcode) { - if (L->errorJmp) { - L->errorJmp->status = errcode; - LUAI_THROW(L, L->errorJmp); - } - else { - L->status = cast_byte(errcode); - if (G(L)->panic) { - resetstack(L, errcode); - lua_unlock(L); - G(L)->panic(L); + else { /* thread has no error handler */ + L->status = cast_byte(errcode); /* mark it as dead */ + if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */ + setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */ + luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */ + } + else { /* no handler at all; abort */ + if (G(L)->panic) { /* panic function? */ + lua_unlock(L); + G(L)->panic(L); /* call it (last chance to jump out) */ + } + abort(); } - exit(EXIT_FAILURE); } } int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + unsigned short oldnCcalls = L->nCcalls; struct lua_longjmp lj; - lj.status = 0; + lj.status = LUA_OK; lj.previous = L->errorJmp; /* chain new error handler */ L->errorJmp = &lj; LUAI_TRY(L, &lj, (*f)(L, ud); ); L->errorJmp = lj.previous; /* restore old error handler */ + L->nCcalls = oldnCcalls; return lj.status; } @@ -129,112 +145,126 @@ static void correctstack (lua_State *L, TValue *oldstack) { L->top = (L->top - oldstack) + L->stack; for (up = L->openupval; up != NULL; up = up->gch.next) gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; - for (ci = L->base_ci; ci <= L->ci; ci++) { + for (ci = L->ci; ci != NULL; ci = ci->previous) { ci->top = (ci->top - oldstack) + L->stack; - ci->base = (ci->base - oldstack) + L->stack; ci->func = (ci->func - oldstack) + L->stack; + if (isLua(ci)) + ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; } - L->base = (L->base - oldstack) + L->stack; } +/* some space for error handling */ +#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) + + void luaD_reallocstack (lua_State *L, int newsize) { TValue *oldstack = L->stack; - int realsize = newsize + 1 + EXTRA_STACK; - lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); - luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); - L->stacksize = realsize; - L->stack_last = L->stack+newsize; + int lim = L->stacksize; + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); + for (; lim < newsize; lim++) + setnilvalue(L->stack + lim); /* erase new segment */ + L->stacksize = newsize; + L->stack_last = L->stack + newsize - EXTRA_STACK; correctstack(L, oldstack); } -void luaD_reallocCI (lua_State *L, int newsize) { - CallInfo *oldci = L->base_ci; - luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); - L->size_ci = newsize; - L->ci = (L->ci - oldci) + L->base_ci; - L->end_ci = L->base_ci + L->size_ci - 1; -} - - void luaD_growstack (lua_State *L, int n) { - if (n <= L->stacksize) /* double size is enough? */ - luaD_reallocstack(L, 2*L->stacksize); - else - luaD_reallocstack(L, L->stacksize + n); -} - - -static CallInfo *growCI (lua_State *L) { - if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ + int size = L->stacksize; + if (size > LUAI_MAXSTACK) /* error after extra size? */ luaD_throw(L, LUA_ERRERR); else { - luaD_reallocCI(L, 2*L->size_ci); - if (L->size_ci > LUAI_MAXCALLS) + int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; + int newsize = 2 * size; + if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; + if (newsize < needed) newsize = needed; + if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ + luaD_reallocstack(L, ERRORSTACKSIZE); luaG_runerror(L, "stack overflow"); + } + else + luaD_reallocstack(L, newsize); } - return ++L->ci; } -void luaD_callhook (lua_State *L, int event, int line) { +static int stackinuse (lua_State *L) { + CallInfo *ci; + StkId lim = L->top; + for (ci = L->ci; ci != NULL; ci = ci->previous) { + lua_assert(ci->top <= L->stack_last); + if (lim < ci->top) lim = ci->top; + } + return cast_int(lim - L->stack) + 1; /* part of stack in use */ +} + + +void luaD_shrinkstack (lua_State *L) { + int inuse = stackinuse(L); + int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; + if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; + if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */ + goodsize >= L->stacksize) /* would grow instead of shrink? */ + condmovestack(L); /* don't change stack (change only for debugging) */ + else + luaD_reallocstack(L, goodsize); /* shrink it */ +} + + +void luaD_hook (lua_State *L, int event, int line) { lua_Hook hook = L->hook; if (hook && L->allowhook) { + CallInfo *ci = L->ci; ptrdiff_t top = savestack(L, L->top); - ptrdiff_t ci_top = savestack(L, L->ci->top); + ptrdiff_t ci_top = savestack(L, ci->top); lua_Debug ar; ar.event = event; ar.currentline = line; - if (event == LUA_HOOKTAILRET) - ar.i_ci = 0; /* tail call; no debug information about it */ - else - ar.i_ci = cast_int(L->ci - L->base_ci); + ar.i_ci = ci; luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - L->ci->top = L->top + LUA_MINSTACK; - lua_assert(L->ci->top <= L->stack_last); + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); L->allowhook = 0; /* cannot call hooks inside a hook */ + ci->callstatus |= CIST_HOOKED; lua_unlock(L); (*hook)(L, &ar); lua_lock(L); lua_assert(!L->allowhook); L->allowhook = 1; - L->ci->top = restorestack(L, ci_top); + ci->top = restorestack(L, ci_top); L->top = restorestack(L, top); + ci->callstatus &= ~CIST_HOOKED; } } +static void callhook (lua_State *L, CallInfo *ci) { + int hook = LUA_HOOKCALL; + ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ + if (isLua(ci->previous) && + GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { + ci->callstatus |= CIST_TAIL; + hook = LUA_HOOKTAILCALL; + } + luaD_hook(L, hook, -1); + ci->u.l.savedpc--; /* correct 'pc' */ +} + + static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { int i; int nfixargs = p->numparams; - Table *htab = NULL; StkId base, fixed; - for (; actual < nfixargs; ++actual) - setnilvalue(L->top++); -#if defined(LUA_COMPAT_VARARG) - if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ - int nvar = actual - nfixargs; /* number of extra arguments */ - lua_assert(p->is_vararg & VARARG_HASARG); - luaC_checkGC(L); - htab = luaH_new(L, nvar, 1); /* create `arg' table */ - for (i=0; itop - nvar + i); - /* store counter in field `n' */ - setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); - } -#endif + lua_assert(actual >= nfixargs); /* move fixed parameters to final position */ fixed = L->top - actual; /* first fixed argument */ base = L->top; /* final position of first argument */ for (i=0; itop++, fixed+i); - setnilvalue(fixed+i); - } - /* add `arg' parameter */ - if (htab) { - sethvalue(L, L->top++, htab); - lua_assert(iswhite(obj2gco(htab))); + setobjs2s(L, L->top++, fixed + i); + setnilvalue(fixed + i); } return base; } @@ -256,100 +286,87 @@ static StkId tryfuncTM (lua_State *L, StkId func) { -#define inc_ci(L) \ - ((L->ci == L->end_ci) ? growCI(L) : \ - (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) +#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) +/* +** returns true if function has been executed (C function) +*/ int luaD_precall (lua_State *L, StkId func, int nresults) { - LClosure *cl; - ptrdiff_t funcr; - if (!ttisfunction(func)) /* `func' is not a function? */ - func = tryfuncTM(L, func); /* check the `function' tag method */ - funcr = savestack(L, func); - cl = &clvalue(func)->l; - L->ci->savedpc = L->savedpc; - if (!cl->isC) { /* Lua function? prepare its call */ - CallInfo *ci; - StkId st, base; - Proto *p = cl->p; - luaD_checkstack(L, p->maxstacksize); - func = restorestack(L, funcr); - if (!p->is_vararg) { /* no varargs? */ - base = func + 1; - if (L->top > base + p->numparams) - L->top = base + p->numparams; - } - else { /* vararg function */ - int nargs = cast_int(L->top - func) - 1; - base = adjust_varargs(L, p, nargs); - func = restorestack(L, funcr); /* previous call may change the stack */ - } - ci = inc_ci(L); /* now `enter' new function */ - ci->func = func; - L->base = ci->base = base; - ci->top = L->base + p->maxstacksize; - lua_assert(ci->top <= L->stack_last); - L->savedpc = p->code; /* starting point */ - ci->tailcalls = 0; - ci->nresults = nresults; - for (st = L->top; st < ci->top; st++) - setnilvalue(st); - L->top = ci->top; - if (L->hookmask & LUA_MASKCALL) { - L->savedpc++; /* hooks assume 'pc' is already incremented */ - luaD_callhook(L, LUA_HOOKCALL, -1); - L->savedpc--; /* correct 'pc' */ - } - return PCRLUA; - } - else { /* if is a C function, call it */ - CallInfo *ci; - int n; - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - ci = inc_ci(L); /* now `enter' new function */ - ci->func = restorestack(L, funcr); - L->base = ci->base = ci->func + 1; - ci->top = L->top + LUA_MINSTACK; - lua_assert(ci->top <= L->stack_last); - ci->nresults = nresults; - if (L->hookmask & LUA_MASKCALL) - luaD_callhook(L, LUA_HOOKCALL, -1); - lua_unlock(L); - n = (*curr_func(L)->c.f)(L); /* do the actual call */ - lua_lock(L); - if (n < 0) /* yielding? */ - return PCRYIELD; - else { + lua_CFunction f; + CallInfo *ci; + int n; /* number of arguments (Lua) or returns (C) */ + ptrdiff_t funcr = savestack(L, func); + switch (ttype(func)) { + case LUA_TLCF: /* light C function */ + f = fvalue(func); + goto Cfunc; + case LUA_TCCL: { /* C closure */ + f = clCvalue(func)->f; + Cfunc: + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = restorestack(L, funcr); + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->callstatus = 0; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); luaD_poscall(L, L->top - n); - return PCRC; + return 1; + } + case LUA_TLCL: { /* Lua function: prepare its call */ + StkId base; + Proto *p = clLvalue(func)->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + n = cast_int(L->top - func) - 1; /* number of real arguments */ + for (; n < p->numparams; n++) + setnilvalue(L->top++); /* complete missing arguments */ + base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n); + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->u.l.base = base; + ci->top = base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus = CIST_LUA; + L->top = ci->top; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + callhook(L, ci); + return 0; + } + default: { /* not a function */ + func = tryfuncTM(L, func); /* retry with 'function' tag method */ + return luaD_precall(L, func, nresults); /* now it must be a function */ } } } -static StkId callrethooks (lua_State *L, StkId firstResult) { - ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ - luaD_callhook(L, LUA_HOOKRET, -1); - if (f_isLua(L->ci)) { /* Lua function? */ - while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ - luaD_callhook(L, LUA_HOOKTAILRET, -1); - } - return restorestack(L, fr); -} - - int luaD_poscall (lua_State *L, StkId firstResult) { StkId res; int wanted, i; - CallInfo *ci; - if (L->hookmask & LUA_MASKRET) - firstResult = callrethooks(L, firstResult); - ci = L->ci--; + CallInfo *ci = L->ci; + if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { + if (L->hookmask & LUA_MASKRET) { + ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ + luaD_hook(L, LUA_HOOKRET, -1); + firstResult = restorestack(L, fr); + } + L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ + } res = ci->func; /* res == final position of 1st result */ wanted = ci->nresults; - L->base = (ci - 1)->base; /* restore base */ - L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ + L->ci = ci = ci->previous; /* back to caller */ /* move results to correct place */ for (i = wanted; i != 0 && firstResult < L->top; i--) setobjs2s(L, res++, firstResult++); @@ -365,112 +382,225 @@ int luaD_poscall (lua_State *L, StkId firstResult) { ** The arguments are on the stack, right after the function. ** When returns, all the results are on the stack, starting at the original ** function position. -*/ -void luaD_call (lua_State *L, StkId func, int nResults) { +*/ +void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { if (++L->nCcalls >= LUAI_MAXCCALLS) { if (L->nCcalls == LUAI_MAXCCALLS) luaG_runerror(L, "C stack overflow"); else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ } - if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ - luaV_execute(L, 1); /* call it */ + if (!allowyield) L->nny++; + if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ + luaV_execute(L); /* call it */ + if (!allowyield) L->nny--; L->nCcalls--; - luaC_checkGC(L); } +static void finishCcall (lua_State *L) { + CallInfo *ci = L->ci; + int n; + lua_assert(ci->u.c.k != NULL); /* must have a continuation */ + lua_assert(L->nny == 0); + if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ + ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ + L->errfunc = ci->u.c.old_errfunc; + } + /* finish 'lua_callk'/'lua_pcall' */ + adjustresults(L, ci->nresults); + /* call continuation function */ + if (!(ci->callstatus & CIST_STAT)) /* no call status? */ + ci->u.c.status = LUA_YIELD; /* 'default' status */ + lua_assert(ci->u.c.status != LUA_OK); + ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); + lua_lock(L); + api_checknelems(L, n); + /* finish 'luaD_precall' */ + luaD_poscall(L, L->top - n); +} + + +static void unroll (lua_State *L, void *ud) { + UNUSED(ud); + for (;;) { + if (L->ci == &L->base_ci) /* stack is empty? */ + return; /* coroutine finished normally */ + if (!isLua(L->ci)) /* C function? */ + finishCcall(L); + else { /* Lua function */ + luaV_finishOp(L); /* finish interrupted instruction */ + luaV_execute(L); /* execute down to higher C 'boundary' */ + } + } +} + + +/* +** check whether thread has a suspended protected call +*/ +static CallInfo *findpcall (lua_State *L) { + CallInfo *ci; + for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ + if (ci->callstatus & CIST_YPCALL) + return ci; + } + return NULL; /* no pending pcall */ +} + + +static int recover (lua_State *L, int status) { + StkId oldtop; + CallInfo *ci = findpcall(L); + if (ci == NULL) return 0; /* no recovery point */ + /* "finish" luaD_pcall */ + oldtop = restorestack(L, ci->extra); + luaF_close(L, oldtop); + seterrorobj(L, status, oldtop); + L->ci = ci; + L->allowhook = ci->u.c.old_allowhook; + L->nny = 0; /* should be zero to be yieldable */ + luaD_shrinkstack(L); + L->errfunc = ci->u.c.old_errfunc; + ci->callstatus |= CIST_STAT; /* call has error status */ + ci->u.c.status = status; /* (here it is) */ + return 1; /* continue running the coroutine */ +} + + +/* +** signal an error in the call to 'resume', not in the execution of the +** coroutine itself. (Such errors should not be handled by any coroutine +** error handler and should not kill the coroutine.) +*/ +static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { + L->top = firstArg; /* remove args from the stack */ + setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ + api_incr_top(L); + luaD_throw(L, -1); /* jump back to 'lua_resume' */ +} + + +/* +** do the work for 'lua_resume' in protected mode +*/ static void resume (lua_State *L, void *ud) { + int nCcalls = L->nCcalls; StkId firstArg = cast(StkId, ud); CallInfo *ci = L->ci; - if (L->status == 0) { /* start coroutine? */ - lua_assert(ci == L->base_ci && firstArg > L->base); - if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) - return; + if (nCcalls >= LUAI_MAXCCALLS) + resume_error(L, "C stack overflow", firstArg); + if (L->status == LUA_OK) { /* may be starting a coroutine */ + if (ci != &L->base_ci) /* not in base level? */ + resume_error(L, "cannot resume non-suspended coroutine", firstArg); + /* coroutine is in base level; start running it */ + if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ + luaV_execute(L); /* call it */ } + else if (L->status != LUA_YIELD) + resume_error(L, "cannot resume dead coroutine", firstArg); else { /* resuming from previous yield */ - lua_assert(L->status == LUA_YIELD); - L->status = 0; - if (!f_isLua(ci)) { /* `common' yield? */ - /* finish interrupted execution of `OP_CALL' */ - lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || - GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); - if (luaD_poscall(L, firstArg)) /* complete it... */ - L->top = L->ci->top; /* and correct top if not multiple results */ + L->status = LUA_OK; + ci->func = restorestack(L, ci->extra); + if (isLua(ci)) /* yielded inside a hook? */ + luaV_execute(L); /* just continue running Lua code */ + else { /* 'common' yield */ + if (ci->u.c.k != NULL) { /* does it have a continuation? */ + int n; + ci->u.c.status = LUA_YIELD; /* 'default' status */ + ci->callstatus |= CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + firstArg = L->top - n; /* yield results come from continuation */ + } + luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ } - else /* yielded inside a hook: just continue its execution */ - L->base = L->ci->base; + unroll(L, NULL); } - luaV_execute(L, cast_int(L->ci - L->base_ci)); + lua_assert(nCcalls == L->nCcalls); } -static int resume_error (lua_State *L, const char *msg) { - L->top = L->ci->base; - setsvalue2s(L, L->top, luaS_new(L, msg)); - incr_top(L); - lua_unlock(L); - return LUA_ERRRUN; -} - - -LUA_API int lua_resume (lua_State *L, int nargs) { +LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { int status; lua_lock(L); - if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) - return resume_error(L, "cannot resume non-suspended coroutine"); - if (L->nCcalls >= LUAI_MAXCCALLS) - return resume_error(L, "C stack overflow"); luai_userstateresume(L, nargs); - lua_assert(L->errfunc == 0); - L->baseCcalls = ++L->nCcalls; + L->nCcalls = (from) ? from->nCcalls + 1 : 1; + L->nny = 0; /* allow yields */ + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); status = luaD_rawrunprotected(L, resume, L->top - nargs); - if (status != 0) { /* error? */ - L->status = cast_byte(status); /* mark thread as `dead' */ - luaD_seterrorobj(L, status, L->top); - L->ci->top = L->top; + if (status == -1) /* error calling 'lua_resume'? */ + status = LUA_ERRRUN; + else { /* yield or regular error */ + while (status != LUA_OK && status != LUA_YIELD) { /* error? */ + if (recover(L, status)) /* recover point? */ + status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ + else { /* unrecoverable error */ + L->status = cast_byte(status); /* mark thread as `dead' */ + seterrorobj(L, status, L->top); + L->ci->top = L->top; + break; + } + } + lua_assert(status == L->status); } - else { - lua_assert(L->nCcalls == L->baseCcalls); - status = L->status; - } - --L->nCcalls; + L->nny = 1; /* do not allow yields */ + L->nCcalls--; + lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); lua_unlock(L); return status; } -LUA_API int lua_yield (lua_State *L, int nresults) { +LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) { + CallInfo *ci = L->ci; luai_userstateyield(L, nresults); lua_lock(L); - if (L->nCcalls > L->baseCcalls) - luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); - L->base = L->top - nresults; /* protect stack slots below */ + api_checknelems(L, nresults); + if (L->nny > 0) { + if (L != G(L)->mainthread) + luaG_runerror(L, "attempt to yield across a C-call boundary"); + else + luaG_runerror(L, "attempt to yield from outside a coroutine"); + } L->status = LUA_YIELD; + ci->extra = savestack(L, ci->func); /* save current 'func' */ + if (isLua(ci)) { /* inside a hook? */ + api_check(L, k == NULL, "hooks cannot continue after yielding"); + } + else { + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ + ci->u.c.ctx = ctx; /* save context */ + ci->func = L->top - nresults - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } + lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ lua_unlock(L); - return -1; + return 0; /* return to 'luaD_hook' */ } int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t old_top, ptrdiff_t ef) { int status; - unsigned short oldnCcalls = L->nCcalls; - ptrdiff_t old_ci = saveci(L, L->ci); + CallInfo *old_ci = L->ci; lu_byte old_allowhooks = L->allowhook; + unsigned short old_nny = L->nny; ptrdiff_t old_errfunc = L->errfunc; L->errfunc = ef; status = luaD_rawrunprotected(L, func, u); - if (status != 0) { /* an error occurred? */ + if (status != LUA_OK) { /* an error occurred? */ StkId oldtop = restorestack(L, old_top); - luaF_close(L, oldtop); /* close eventual pending closures */ - luaD_seterrorobj(L, status, oldtop); - L->nCcalls = oldnCcalls; - L->ci = restoreci(L, old_ci); - L->base = L->ci->base; - L->savedpc = L->ci->savedpc; + luaF_close(L, oldtop); /* close possible pending closures */ + seterrorobj(L, status, oldtop); + L->ci = old_ci; L->allowhook = old_allowhooks; - restore_stack_limit(L); + L->nny = old_nny; + luaD_shrinkstack(L); } L->errfunc = old_errfunc; return status; @@ -483,35 +613,60 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, */ struct SParser { /* data to `f_parser' */ ZIO *z; - Mbuffer buff; /* buffer to be used by the scanner */ + Mbuffer buff; /* dynamic structure used by the scanner */ + Dyndata dyd; /* dynamic structures used by the parser */ + const char *mode; const char *name; }; -static void f_parser (lua_State *L, void *ud) { - int i; - Proto *tf; - Closure *cl; - struct SParser *p = cast(struct SParser *, ud); - int c = luaZ_lookahead(p->z); - luaC_checkGC(L); - tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, - &p->buff, p->name); - cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); - cl->l.p = tf; - for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ - cl->l.upvals[i] = luaF_newupval(L); - setclvalue(L, L->top, cl); - incr_top(L); + +static void checkmode (lua_State *L, const char *mode, const char *x) { + if (mode && strchr(mode, x[0]) == NULL) { + luaO_pushfstring(L, + "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); + luaD_throw(L, LUA_ERRSYNTAX); + } } -int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { +static void f_parser (lua_State *L, void *ud) { + int i; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = zgetc(p->z); /* read first character */ + if (c == LUA_SIGNATURE[0]) { + checkmode(L, p->mode, "binary"); + cl = luaU_undump(L, p->z, &p->buff, p->name); + } + else { + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); + } + lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); + for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */ + UpVal *up = luaF_newupval(L); + cl->l.upvals[i] = up; + luaC_objbarrier(L, cl, up); + } +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode) { struct SParser p; int status; - p.z = z; p.name = name; + L->nny++; /* cannot yield during parsing */ + p.z = z; p.name = name; p.mode = mode; + p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; + p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; + p.dyd.label.arr = NULL; p.dyd.label.size = 0; luaZ_initbuffer(L, &p.buff); status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); luaZ_freebuffer(L, &p.buff); + luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); + luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); + luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); + L->nny--; return status; } diff --git a/src/mod/languages/mod_lua/lua/ldo.h b/src/mod/languages/mod_lua/lua/ldo.h index 98fddac59f..27b837d999 100644 --- a/src/mod/languages/mod_lua/lua/ldo.h +++ b/src/mod/languages/mod_lua/lua/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: ldo.h,v 2.20 2011/11/29 15:55:08 roberto Exp $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -13,45 +13,34 @@ #include "lzio.h" -#define luaD_checkstack(L,n) \ - if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ - luaD_growstack(L, n); \ - else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); +#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ + luaD_growstack(L, n); else condmovestack(L); -#define incr_top(L) {luaD_checkstack(L,1); L->top++;} +#define incr_top(L) {L->top++; luaD_checkstack(L,0);} #define savestack(L,p) ((char *)(p) - (char *)L->stack) #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) -#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) -#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) - - -/* results from luaD_precall */ -#define PCRLUA 0 /* initiated a call to a Lua function */ -#define PCRC 1 /* did a call to a C function */ -#define PCRYIELD 2 /* C funtion yielded */ - /* type of protected functions, to be ran by `runprotected' */ typedef void (*Pfunc) (lua_State *L, void *ud); -LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); -LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); -LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, + int allowyield); LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t oldtop, ptrdiff_t ef); LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); -LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); LUAI_FUNC void luaD_growstack (lua_State *L, int n); +LUAI_FUNC void luaD_shrinkstack (lua_State *L); -LUAI_FUNC void luaD_throw (lua_State *L, int errcode); +LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); -LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); - #endif diff --git a/src/mod/languages/mod_lua/lua/ldump.c b/src/mod/languages/mod_lua/lua/ldump.c index c9d3d4870f..d5e6a47cb3 100644 --- a/src/mod/languages/mod_lua/lua/ldump.c +++ b/src/mod/languages/mod_lua/lua/ldump.c @@ -1,5 +1,5 @@ /* -** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: ldump.c,v 2.17 2012/01/23 23:02:10 roberto Exp $ ** save precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -24,7 +24,7 @@ typedef struct { } DumpState; #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) -#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) static void DumpBlock(const void* b, size_t size, DumpState* D) { @@ -60,7 +60,7 @@ static void DumpVector(const void* b, int n, size_t size, DumpState* D) static void DumpString(const TString* s, DumpState* D) { - if (s==NULL || getstr(s)==NULL) + if (s==NULL) { size_t size=0; DumpVar(size,D); @@ -69,13 +69,13 @@ static void DumpString(const TString* s, DumpState* D) { size_t size=s->tsv.len+1; /* include trailing '\0' */ DumpVar(size,D); - DumpBlock(getstr(s),size,D); + DumpBlock(getstr(s),size*sizeof(char),D); } } #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) -static void DumpFunction(const Proto* f, const TString* p, DumpState* D); +static void DumpFunction(const Proto* f, DumpState* D); static void DumpConstants(const Proto* f, DumpState* D) { @@ -84,8 +84,8 @@ static void DumpConstants(const Proto* f, DumpState* D) for (i=0; ik[i]; - DumpChar(ttype(o),D); - switch (ttype(o)) + DumpChar(ttypenv(o),D); + switch (ttypenv(o)) { case LUA_TNIL: break; @@ -98,19 +98,29 @@ static void DumpConstants(const Proto* f, DumpState* D) case LUA_TSTRING: DumpString(rawtsvalue(o),D); break; - default: - lua_assert(0); /* cannot happen */ - break; + default: lua_assert(0); } } n=f->sizep; DumpInt(n,D); - for (i=0; ip[i],f->source,D); + for (i=0; ip[i],D); +} + +static void DumpUpvalues(const Proto* f, DumpState* D) +{ + int i,n=f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i].instack,D); + DumpChar(f->upvalues[i].idx,D); + } } static void DumpDebug(const Proto* f, DumpState* D) { int i,n; + DumpString((D->strip) ? NULL : f->source,D); n= (D->strip) ? 0 : f->sizelineinfo; DumpVector(f->lineinfo,n,sizeof(int),D); n= (D->strip) ? 0 : f->sizelocvars; @@ -123,26 +133,25 @@ static void DumpDebug(const Proto* f, DumpState* D) } n= (D->strip) ? 0 : f->sizeupvalues; DumpInt(n,D); - for (i=0; iupvalues[i],D); + for (i=0; iupvalues[i].name,D); } -static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +static void DumpFunction(const Proto* f, DumpState* D) { - DumpString((f->source==p || D->strip) ? NULL : f->source,D); DumpInt(f->linedefined,D); DumpInt(f->lastlinedefined,D); - DumpChar(f->nups,D); DumpChar(f->numparams,D); DumpChar(f->is_vararg,D); DumpChar(f->maxstacksize,D); DumpCode(f,D); DumpConstants(f,D); + DumpUpvalues(f,D); DumpDebug(f,D); } static void DumpHeader(DumpState* D) { - char h[LUAC_HEADERSIZE]; + lu_byte h[LUAC_HEADERSIZE]; luaU_header(h); DumpBlock(h,LUAC_HEADERSIZE,D); } @@ -159,6 +168,6 @@ int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip D.strip=strip; D.status=0; DumpHeader(&D); - DumpFunction(f,NULL,&D); + DumpFunction(f,&D); return D.status; } diff --git a/src/mod/languages/mod_lua/lua/lfunc.c b/src/mod/languages/mod_lua/lua/lfunc.c index 813e88f583..c2128405b9 100644 --- a/src/mod/languages/mod_lua/lua/lfunc.c +++ b/src/mod/languages/mod_lua/lua/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ +** $Id: lfunc.c,v 2.30 2012/10/03 12:36:46 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -20,30 +20,24 @@ -Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { - Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); - luaC_link(L, obj2gco(c), LUA_TFUNCTION); - c->c.isC = 1; - c->c.env = e; - c->c.nupvalues = cast_byte(nelems); +Closure *luaF_newCclosure (lua_State *L, int n) { + Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; + c->c.nupvalues = cast_byte(n); return c; } -Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { - Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); - luaC_link(L, obj2gco(c), LUA_TFUNCTION); - c->l.isC = 0; - c->l.env = e; - c->l.nupvalues = cast_byte(nelems); - while (nelems--) c->l.upvals[nelems] = NULL; +Closure *luaF_newLclosure (lua_State *L, int n) { + Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; + c->l.p = NULL; + c->l.nupvalues = cast_byte(n); + while (n--) c->l.upvals[n] = NULL; return c; } UpVal *luaF_newupval (lua_State *L) { - UpVal *uv = luaM_new(L, UpVal); - luaC_link(L, obj2gco(uv), LUA_TUPVAL); + UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; uv->v = &uv->u.value; setnilvalue(uv->v); return uv; @@ -55,21 +49,20 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { GCObject **pp = &L->openupval; UpVal *p; UpVal *uv; - while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { + while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { + GCObject *o = obj2gco(p); lua_assert(p->v != &p->u.value); + lua_assert(!isold(o) || isold(obj2gco(L))); if (p->v == level) { /* found a corresponding upvalue? */ - if (isdead(g, obj2gco(p))) /* is it dead? */ - changewhite(obj2gco(p)); /* ressurect it */ + if (isdead(g, o)) /* is it dead? */ + changewhite(o); /* resurrect it */ return p; } pp = &p->next; } - uv = luaM_new(L, UpVal); /* not found: create a new one */ - uv->tt = LUA_TUPVAL; - uv->marked = luaC_white(g); + /* not found: create a new one */ + uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; uv->v = level; /* current value lives in the stack */ - uv->next = *pp; /* chain it in the proper position */ - *pp = obj2gco(uv); uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ uv->u.l.next = g->uvhead.u.l.next; uv->u.l.next->u.l.prev = uv; @@ -96,41 +89,42 @@ void luaF_freeupval (lua_State *L, UpVal *uv) { void luaF_close (lua_State *L, StkId level) { UpVal *uv; global_State *g = G(L); - while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { + while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { GCObject *o = obj2gco(uv); lua_assert(!isblack(o) && uv->v != &uv->u.value); L->openupval = uv->next; /* remove from `open' list */ if (isdead(g, o)) luaF_freeupval(L, uv); /* free upvalue */ else { - unlinkupval(uv); - setobj(L, &uv->u.value, uv->v); + unlinkupval(uv); /* remove upvalue from 'uvhead' list */ + setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ uv->v = &uv->u.value; /* now current value lives here */ - luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ + gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ + g->allgc = o; + luaC_checkupvalcolor(g, uv); } } } Proto *luaF_newproto (lua_State *L) { - Proto *f = luaM_new(L, Proto); - luaC_link(L, obj2gco(f), LUA_TPROTO); + Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; f->k = NULL; f->sizek = 0; f->p = NULL; f->sizep = 0; f->code = NULL; + f->cache = NULL; f->sizecode = 0; + f->lineinfo = NULL; f->sizelineinfo = 0; - f->sizeupvalues = 0; - f->nups = 0; f->upvalues = NULL; + f->sizeupvalues = 0; f->numparams = 0; f->is_vararg = 0; f->maxstacksize = 0; - f->lineinfo = NULL; - f->sizelocvars = 0; f->locvars = NULL; + f->sizelocvars = 0; f->linedefined = 0; f->lastlinedefined = 0; f->source = NULL; @@ -139,23 +133,16 @@ Proto *luaF_newproto (lua_State *L) { void luaF_freeproto (lua_State *L, Proto *f) { - luaM_freearray(L, f->code, f->sizecode, Instruction); - luaM_freearray(L, f->p, f->sizep, Proto *); - luaM_freearray(L, f->k, f->sizek, TValue); - luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); - luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); - luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); luaM_free(L, f); } -void luaF_freeclosure (lua_State *L, Closure *c) { - int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : - sizeLclosure(c->l.nupvalues); - luaM_freemem(L, c, size); -} - - /* ** Look for n-th local variable at line `line' in function `func'. ** Returns NULL if not found. diff --git a/src/mod/languages/mod_lua/lua/lfunc.h b/src/mod/languages/mod_lua/lua/lfunc.h index a68cf5151c..e236a717c6 100644 --- a/src/mod/languages/mod_lua/lua/lfunc.h +++ b/src/mod/languages/mod_lua/lua/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lfunc.h,v 2.8 2012/05/08 13:53:33 roberto Exp $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -19,13 +19,12 @@ LUAI_FUNC Proto *luaF_newproto (lua_State *L); -LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); -LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); LUAI_FUNC UpVal *luaF_newupval (lua_State *L); LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); LUAI_FUNC void luaF_close (lua_State *L, StkId level); LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); -LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, int pc); diff --git a/src/mod/languages/mod_lua/lua/lgc.c b/src/mod/languages/mod_lua/lua/lgc.c index d9e0b78294..535e988ae0 100644 --- a/src/mod/languages/mod_lua/lua/lgc.c +++ b/src/mod/languages/mod_lua/lua/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lgc.c,v 2.140 2013/03/16 21:10:18 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -23,689 +23,1191 @@ #include "ltm.h" -#define GCSTEPSIZE 1024u -#define GCSWEEPMAX 40 -#define GCSWEEPCOST 10 -#define GCFINALIZECOST 100 + +/* +** cost of sweeping one element (the size of a small object divided +** by some adjust for the sweep speed) +*/ +#define GCSWEEPCOST ((sizeof(TString) + 4) / 4) + +/* maximum number of elements to sweep in each single step */ +#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) + +/* maximum number of finalizers to call in each GC step */ +#define GCFINALIZENUM 4 -#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) +/* +** macro to adjust 'stepmul': 'stepmul' is actually used like +** 'stepmul / STEPMULADJ' (value chosen by tests) +*/ +#define STEPMULADJ 200 + +/* +** macro to adjust 'pause': 'pause' is actually used like +** 'pause / PAUSEADJ' (value chosen by tests) +*/ +#define PAUSEADJ 100 + + +/* +** 'makewhite' erases all color bits plus the old bit and then +** sets only the current white bit +*/ +#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) #define makewhite(g,x) \ - ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) + (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) -#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) -#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) - -#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) +#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) +#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) -#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) -#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) +#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) + +#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) -#define KEYWEAK bitmask(KEYWEAKBIT) -#define VALUEWEAK bitmask(VALUEWEAKBIT) - +#define checkconsistency(obj) \ + lua_longassert(!iscollectable(obj) || righttt(obj)) #define markvalue(g,o) { checkconsistency(o); \ - if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } + if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } -#define markobject(g,t) { if (iswhite(obj2gco(t))) \ +#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ reallymarkobject(g, obj2gco(t)); } - -#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) +static void reallymarkobject (global_State *g, GCObject *o); +/* +** {====================================================== +** Generic functions +** ======================================================= +*/ + + +/* +** one after last element in a hash array +*/ +#define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) + + +/* +** link table 'h' into list pointed by 'p' +*/ +#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h)) + + +/* +** if key is not marked, mark its entry as dead (therefore removing it +** from the table) +*/ static void removeentry (Node *n) { lua_assert(ttisnil(gval(n))); - if (iscollectable(gkey(n))) - setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ + if (valiswhite(gkey(n))) + setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */ } +/* +** tells whether a key or value can be cleared from a weak +** table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for objects +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (global_State *g, const TValue *o) { + if (!iscollectable(o)) return 0; + else if (ttisstring(o)) { + markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + else return iswhite(gcvalue(o)); +} + + +/* +** barrier that moves collector forward, that is, mark the white object +** being pointed by a black object. +*/ +void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSpause); + lua_assert(gch(o)->tt != LUA_TTABLE); + if (keepinvariantout(g)) /* must keep invariant? */ + reallymarkobject(g, v); /* restore invariant */ + else { /* sweep phase */ + lua_assert(issweepphase(g)); + makewhite(g, o); /* mark main obj. as white to avoid other barriers */ + } +} + + +/* +** barrier that moves collector backward, that is, mark the black object +** pointing to a white object as gray again. (Current implementation +** only works for tables; access to 'gclist' is not uniform across +** different types.) +*/ +void luaC_barrierback_ (lua_State *L, GCObject *o) { + global_State *g = G(L); + lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); + black2gray(o); /* make object gray (again) */ + gco2t(o)->gclist = g->grayagain; + g->grayagain = o; +} + + +/* +** barrier for prototypes. When creating first closure (cache is +** NULL), use a forward barrier; this may be the only closure of the +** prototype (if it is a "regular" function, with a single instance) +** and the prototype may be big, so it is better to avoid traversing +** it again. Otherwise, use a backward barrier, to avoid marking all +** possible instances. +*/ +LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) { + global_State *g = G(L); + lua_assert(isblack(obj2gco(p))); + if (p->cache == NULL) { /* first time? */ + luaC_objbarrier(L, p, c); + } + else { /* use a backward barrier */ + black2gray(obj2gco(p)); /* make prototype gray (again) */ + p->gclist = g->grayagain; + g->grayagain = obj2gco(p); + } +} + + +/* +** check color (and invariants) for an upvalue that was closed, +** i.e., moved into the 'allgc' list +*/ +void luaC_checkupvalcolor (global_State *g, UpVal *uv) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o)); /* open upvalues are never black */ + if (isgray(o)) { + if (keepinvariant(g)) { + resetoldbit(o); /* see MOVE OLD rule */ + gray2black(o); /* it is being visited now */ + markvalue(g, uv->v); + } + else { + lua_assert(issweepphase(g)); + makewhite(g, o); + } + } +} + + +/* +** create a new collectable object (with given type and size) and link +** it to '*list'. 'offset' tells how many bytes to allocate before the +** object itself (used only by states). +*/ +GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, + int offset) { + global_State *g = G(L); + char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz)); + GCObject *o = obj2gco(raw + offset); + if (list == NULL) + list = &g->allgc; /* standard list for collectable objects */ + gch(o)->marked = luaC_white(g); + gch(o)->tt = tt; + gch(o)->next = *list; + *list = o; + return o; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** Mark functions +** ======================================================= +*/ + + +/* +** mark an object. Userdata, strings, and closed upvalues are visited +** and turned black here. Other objects are marked gray and added +** to appropriate list to be visited (and turned black) later. (Open +** upvalues are already linked in 'headuv' list.) +*/ static void reallymarkobject (global_State *g, GCObject *o) { - lua_assert(iswhite(o) && !isdead(g, o)); + lu_mem size; white2gray(o); - switch (o->gch.tt) { - case LUA_TSTRING: { - return; + switch (gch(o)->tt) { + case LUA_TSHRSTR: + case LUA_TLNGSTR: { + size = sizestring(gco2ts(o)); + break; /* nothing else to mark; make it black */ } case LUA_TUSERDATA: { Table *mt = gco2u(o)->metatable; - gray2black(o); /* udata are never gray */ - if (mt) markobject(g, mt); + markobject(g, mt); markobject(g, gco2u(o)->env); - return; + size = sizeudata(gco2u(o)); + break; } case LUA_TUPVAL: { UpVal *uv = gco2uv(o); markvalue(g, uv->v); - if (uv->v == &uv->u.value) /* closed? */ - gray2black(o); /* open upvalues are never black */ + if (uv->v != &uv->u.value) /* open? */ + return; /* open upvalues remain gray */ + size = sizeof(UpVal); + break; + } + case LUA_TLCL: { + gco2lcl(o)->gclist = g->gray; + g->gray = o; return; } - case LUA_TFUNCTION: { - gco2cl(o)->c.gclist = g->gray; + case LUA_TCCL: { + gco2ccl(o)->gclist = g->gray; g->gray = o; - break; + return; } case LUA_TTABLE: { - gco2h(o)->gclist = g->gray; - g->gray = o; - break; + linktable(gco2t(o), &g->gray); + return; } case LUA_TTHREAD: { gco2th(o)->gclist = g->gray; g->gray = o; - break; + return; } case LUA_TPROTO: { gco2p(o)->gclist = g->gray; g->gray = o; - break; + return; } - default: lua_assert(0); + default: lua_assert(0); return; } -} - - -static void marktmu (global_State *g) { - GCObject *u = g->tmudata; - if (u) { - do { - u = u->gch.next; - makewhite(g, u); /* may be marked, if left from previous GC */ - reallymarkobject(g, u); - } while (u != g->tmudata); - } -} - - -/* move `dead' udata that need finalization to list `tmudata' */ -size_t luaC_separateudata (lua_State *L, int all) { - global_State *g = G(L); - size_t deadmem = 0; - GCObject **p = &g->mainthread->next; - GCObject *curr; - while ((curr = *p) != NULL) { - if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) - p = &curr->gch.next; /* don't bother with them */ - else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { - markfinalized(gco2u(curr)); /* don't need finalization */ - p = &curr->gch.next; - } - else { /* must call its gc method */ - deadmem += sizeudata(gco2u(curr)); - markfinalized(gco2u(curr)); - *p = curr->gch.next; - /* link `curr' at the end of `tmudata' list */ - if (g->tmudata == NULL) /* list is empty? */ - g->tmudata = curr->gch.next = curr; /* creates a circular list */ - else { - curr->gch.next = g->tmudata->gch.next; - g->tmudata->gch.next = curr; - g->tmudata = curr; - } - } - } - return deadmem; -} - - -static int traversetable (global_State *g, Table *h) { - int i; - int weakkey = 0; - int weakvalue = 0; - const TValue *mode; - if (h->metatable) - markobject(g, h->metatable); - mode = gfasttm(g, h->metatable, TM_MODE); - if (mode && ttisstring(mode)) { /* is there a weak mode? */ - weakkey = (strchr(svalue(mode), 'k') != NULL); - weakvalue = (strchr(svalue(mode), 'v') != NULL); - if (weakkey || weakvalue) { /* is really weak? */ - h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ - h->marked |= cast_byte((weakkey << KEYWEAKBIT) | - (weakvalue << VALUEWEAKBIT)); - h->gclist = g->weak; /* must be cleared after GC, ... */ - g->weak = obj2gco(h); /* ... so put in the appropriate list */ - } - } - if (weakkey && weakvalue) return 1; - if (!weakvalue) { - i = h->sizearray; - while (i--) - markvalue(g, &h->array[i]); - } - i = sizenode(h); - while (i--) { - Node *n = gnode(h, i); - lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); - if (ttisnil(gval(n))) - removeentry(n); /* remove empty entries */ - else { - lua_assert(!ttisnil(gkey(n))); - if (!weakkey) markvalue(g, gkey(n)); - if (!weakvalue) markvalue(g, gval(n)); - } - } - return weakkey || weakvalue; -} - - -/* -** All marks are conditional because a GC may happen while the -** prototype is still being created -*/ -static void traverseproto (global_State *g, Proto *f) { - int i; - if (f->source) stringmark(f->source); - for (i=0; isizek; i++) /* mark literals */ - markvalue(g, &f->k[i]); - for (i=0; isizeupvalues; i++) { /* mark upvalue names */ - if (f->upvalues[i]) - stringmark(f->upvalues[i]); - } - for (i=0; isizep; i++) { /* mark nested protos */ - if (f->p[i]) - markobject(g, f->p[i]); - } - for (i=0; isizelocvars; i++) { /* mark local-variable names */ - if (f->locvars[i].varname) - stringmark(f->locvars[i].varname); - } -} - - - -static void traverseclosure (global_State *g, Closure *cl) { - markobject(g, cl->c.env); - if (cl->c.isC) { - int i; - for (i=0; ic.nupvalues; i++) /* mark its upvalues */ - markvalue(g, &cl->c.upvalue[i]); - } - else { - int i; - lua_assert(cl->l.nupvalues == cl->l.p->nups); - markobject(g, cl->l.p); - for (i=0; il.nupvalues; i++) /* mark its upvalues */ - markobject(g, cl->l.upvals[i]); - } -} - - -static void checkstacksizes (lua_State *L, StkId max) { - int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ - int s_used = cast_int(max - L->stack); /* part of stack in use */ - if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ - return; /* do not touch the stacks */ - if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) - luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ - condhardstacktests(luaD_reallocCI(L, ci_used + 1)); - if (4*s_used < L->stacksize && - 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) - luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ - condhardstacktests(luaD_reallocstack(L, s_used)); -} - - -static void traversestack (global_State *g, lua_State *l) { - StkId o, lim; - CallInfo *ci; - markvalue(g, gt(l)); - lim = l->top; - for (ci = l->base_ci; ci <= l->ci; ci++) { - lua_assert(ci->top <= l->stack_last); - if (lim < ci->top) lim = ci->top; - } - for (o = l->stack; o < l->top; o++) - markvalue(g, o); - for (; o <= lim; o++) - setnilvalue(o); - checkstacksizes(l, lim); -} - - -/* -** traverse one gray object, turning it to black. -** Returns `quantity' traversed. -*/ -static l_mem propagatemark (global_State *g) { - GCObject *o = g->gray; - lua_assert(isgray(o)); gray2black(o); - switch (o->gch.tt) { - case LUA_TTABLE: { - Table *h = gco2h(o); - g->gray = h->gclist; - if (traversetable(g, h)) /* table is weak? */ - black2gray(o); /* keep it gray */ - return sizeof(Table) + sizeof(TValue) * h->sizearray + - sizeof(Node) * sizenode(h); - } - case LUA_TFUNCTION: { - Closure *cl = gco2cl(o); - g->gray = cl->c.gclist; - traverseclosure(g, cl); - return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : - sizeLclosure(cl->l.nupvalues); - } - case LUA_TTHREAD: { - lua_State *th = gco2th(o); - g->gray = th->gclist; - th->gclist = g->grayagain; - g->grayagain = o; - black2gray(o); - traversestack(g, th); - return sizeof(lua_State) + sizeof(TValue) * th->stacksize + - sizeof(CallInfo) * th->size_ci; - } - case LUA_TPROTO: { - Proto *p = gco2p(o); - g->gray = p->gclist; - traverseproto(g, p); - return sizeof(Proto) + sizeof(Instruction) * p->sizecode + - sizeof(Proto *) * p->sizep + - sizeof(TValue) * p->sizek + - sizeof(int) * p->sizelineinfo + - sizeof(LocVar) * p->sizelocvars + - sizeof(TString *) * p->sizeupvalues; - } - default: lua_assert(0); return 0; - } -} - - -static size_t propagateall (global_State *g) { - size_t m = 0; - while (g->gray) m += propagatemark(g); - return m; + g->GCmemtrav += size; } /* -** The next function tells whether a key or value can be cleared from -** a weak table. Non-collectable objects are never removed from weak -** tables. Strings behave as `values', so are never removed too. for -** other objects: if really collected, cannot keep them; for userdata -** being finalized, keep them in keys, but not in values +** mark metamethods for basic types */ -static int iscleared (const TValue *o, int iskey) { - if (!iscollectable(o)) return 0; - if (ttisstring(o)) { - stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ - return 0; - } - return iswhite(gcvalue(o)) || - (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); -} - - -/* -** clear collected entries from weaktables -*/ -static void cleartable (GCObject *l) { - while (l) { - Table *h = gco2h(l); - int i = h->sizearray; - lua_assert(testbit(h->marked, VALUEWEAKBIT) || - testbit(h->marked, KEYWEAKBIT)); - if (testbit(h->marked, VALUEWEAKBIT)) { - while (i--) { - TValue *o = &h->array[i]; - if (iscleared(o, 0)) /* value was collected? */ - setnilvalue(o); /* remove value */ - } - } - i = sizenode(h); - while (i--) { - Node *n = gnode(h, i); - if (!ttisnil(gval(n)) && /* non-empty entry? */ - (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { - setnilvalue(gval(n)); /* remove value ... */ - removeentry(n); /* remove entry from table */ - } - } - l = h->gclist; - } -} - - -static void freeobj (lua_State *L, GCObject *o) { - switch (o->gch.tt) { - case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; - case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; - case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; - case LUA_TTABLE: luaH_free(L, gco2h(o)); break; - case LUA_TTHREAD: { - lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); - luaE_freethread(L, gco2th(o)); - break; - } - case LUA_TSTRING: { - G(L)->strt.nuse--; - luaM_freemem(L, o, sizestring(gco2ts(o))); - break; - } - case LUA_TUSERDATA: { - luaM_freemem(L, o, sizeudata(gco2u(o))); - break; - } - default: lua_assert(0); - } -} - - - -#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) - - -static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { - GCObject *curr; - global_State *g = G(L); - int deadmask = otherwhite(g); - while ((curr = *p) != NULL && count-- > 0) { - if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ - sweepwholelist(L, &gco2th(curr)->openupval); - if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ - lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); - makewhite(g, curr); /* make it white (for next cycle) */ - p = &curr->gch.next; - } - else { /* must erase `curr' */ - lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); - *p = curr->gch.next; - if (curr == g->rootgc) /* is the first element of the list? */ - g->rootgc = curr->gch.next; /* adjust first */ - freeobj(L, curr); - } - } - return p; -} - - -static void checkSizes (lua_State *L) { - global_State *g = G(L); - /* check size of string hash */ - if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && - g->strt.size > MINSTRTABSIZE*2) - luaS_resize(L, g->strt.size/2); /* table is too big */ - /* check size of buffer */ - if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ - size_t newsize = luaZ_sizebuffer(&g->buff) / 2; - luaZ_resizebuffer(L, &g->buff, newsize); - } -} - - -static void GCTM (lua_State *L) { - global_State *g = G(L); - GCObject *o = g->tmudata->gch.next; /* get first element */ - Udata *udata = rawgco2u(o); - const TValue *tm; - /* remove udata from `tmudata' */ - if (o == g->tmudata) /* last element? */ - g->tmudata = NULL; - else - g->tmudata->gch.next = udata->uv.next; - udata->uv.next = g->mainthread->next; /* return it to `root' list */ - g->mainthread->next = o; - makewhite(g, o); - tm = fasttm(L, udata->uv.metatable, TM_GC); - if (tm != NULL) { - lu_byte oldah = L->allowhook; - lu_mem oldt = g->GCthreshold; - L->allowhook = 0; /* stop debug hooks during GC tag method */ - g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ - setobj2s(L, L->top, tm); - setuvalue(L, L->top+1, udata); - L->top += 2; - luaD_call(L, L->top - 2, 0); - L->allowhook = oldah; /* restore hooks */ - g->GCthreshold = oldt; /* restore threshold */ - } -} - - -/* -** Call all GC tag methods -*/ -void luaC_callGCTM (lua_State *L) { - while (G(L)->tmudata) - GCTM(L); -} - - -void luaC_freeall (lua_State *L) { - global_State *g = G(L); - int i; - g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ - sweepwholelist(L, &g->rootgc); - for (i = 0; i < g->strt.size; i++) /* free all string lists */ - sweepwholelist(L, &g->strt.hash[i]); -} - - static void markmt (global_State *g) { int i; - for (i=0; imt[i]) markobject(g, g->mt[i]); + for (i=0; i < LUA_NUMTAGS; i++) + markobject(g, g->mt[i]); } -/* mark root set */ -static void markroot (lua_State *L) { - global_State *g = G(L); - g->gray = NULL; - g->grayagain = NULL; - g->weak = NULL; - markobject(g, g->mainthread); - /* make global table be traversed before main stack */ - markvalue(g, gt(g->mainthread)); - markvalue(g, registry(L)); - markmt(g); - g->gcstate = GCSpropagate; +/* +** mark all objects in list of being-finalized +*/ +static void markbeingfnz (global_State *g) { + GCObject *o; + for (o = g->tobefnz; o != NULL; o = gch(o)->next) { + makewhite(g, o); + reallymarkobject(g, o); + } } +/* +** mark all values stored in marked open upvalues. (See comment in +** 'lstate.h'.) +*/ static void remarkupvals (global_State *g) { UpVal *uv; for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { - lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); if (isgray(obj2gco(uv))) markvalue(g, uv->v); } } -static void atomic (lua_State *L) { - global_State *g = G(L); - size_t udsize; /* total size of userdata to be finalized */ - /* remark occasional upvalues of (maybe) dead threads */ - remarkupvals(g); - /* traverse objects cautch by write barrier and by 'remarkupvals' */ - propagateall(g); - /* remark weak tables */ - g->gray = g->weak; - g->weak = NULL; - lua_assert(!iswhite(obj2gco(g->mainthread))); - markobject(g, L); /* mark running thread */ - markmt(g); /* mark basic metatables (again) */ - propagateall(g); - /* remark gray again */ - g->gray = g->grayagain; - g->grayagain = NULL; - propagateall(g); - udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ - marktmu(g); /* mark `preserved' userdata */ - udsize += propagateall(g); /* remark, to propagate `preserveness' */ - cleartable(g->weak); /* remove collected objects from weak tables */ - /* flip current white */ - g->currentwhite = cast_byte(otherwhite(g)); - g->sweepstrgc = 0; - g->sweepgc = &g->rootgc; - g->gcstate = GCSsweepstring; - g->estimate = g->totalbytes - udsize; /* first estimate */ +/* +** mark root set and reset all gray lists, to start a new +** incremental (or full) collection +*/ +static void restartcollection (global_State *g) { + g->gray = g->grayagain = NULL; + g->weak = g->allweak = g->ephemeron = NULL; + markobject(g, g->mainthread); + markvalue(g, &g->l_registry); + markmt(g); + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Traverse functions +** ======================================================= +*/ + +static void traverseweakvalue (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + /* if there is array part, assume it may have white values (do not + traverse it just to check) */ + int hasclears = (h->sizearray > 0); + for (n = gnode(h, 0); n < limit; n++) { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ + hasclears = 1; /* table will have to be cleared */ + } + } + if (hasclears) + linktable(h, &g->weak); /* has to be cleared later */ + else /* no white values */ + linktable(h, &g->grayagain); /* no need to clean */ } -static l_mem singlestep (lua_State *L) { +static int traverseephemeron (global_State *g, Table *h) { + int marked = 0; /* true if an object is marked in this traversal */ + int hasclears = 0; /* true if table has white keys */ + int prop = 0; /* true if table has entry "white-key -> white-value" */ + Node *n, *limit = gnodelast(h); + int i; + /* traverse array part (numeric keys are 'strong') */ + for (i = 0; i < h->sizearray; i++) { + if (valiswhite(&h->array[i])) { + marked = 1; + reallymarkobject(g, gcvalue(&h->array[i])); + } + } + /* traverse hash part */ + for (n = gnode(h, 0); n < limit; n++) { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ + hasclears = 1; /* table must be cleared */ + if (valiswhite(gval(n))) /* value not marked yet? */ + prop = 1; /* must propagate again */ + } + else if (valiswhite(gval(n))) { /* value not marked yet? */ + marked = 1; + reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ + } + } + if (prop) + linktable(h, &g->ephemeron); /* have to propagate again */ + else if (hasclears) /* does table have white keys? */ + linktable(h, &g->allweak); /* may have to clean white keys */ + else /* no white keys */ + linktable(h, &g->grayagain); /* no need to clean */ + return marked; +} + + +static void traversestrongtable (global_State *g, Table *h) { + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) /* traverse array part */ + markvalue(g, &h->array[i]); + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + markvalue(g, gval(n)); /* mark value */ + } + } +} + + +static lu_mem traversetable (global_State *g, Table *h) { + const char *weakkey, *weakvalue; + const TValue *mode = gfasttm(g, h->metatable, TM_MODE); + markobject(g, h->metatable); + if (mode && ttisstring(mode) && /* is there a weak mode? */ + ((weakkey = strchr(svalue(mode), 'k')), + (weakvalue = strchr(svalue(mode), 'v')), + (weakkey || weakvalue))) { /* is really weak? */ + black2gray(obj2gco(h)); /* keep table gray */ + if (!weakkey) /* strong keys? */ + traverseweakvalue(g, h); + else if (!weakvalue) /* strong values? */ + traverseephemeron(g, h); + else /* all weak */ + linktable(h, &g->allweak); /* nothing to traverse now */ + } + else /* not weak */ + traversestrongtable(g, h); + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * cast(size_t, sizenode(h)); +} + + +static int traverseproto (global_State *g, Proto *f) { + int i; + if (f->cache && iswhite(obj2gco(f->cache))) + f->cache = NULL; /* allow cache to be collected */ + markobject(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobject(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobject(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobject(g, f->locvars[i].varname); + return sizeof(Proto) + sizeof(Instruction) * f->sizecode + + sizeof(Proto *) * f->sizep + + sizeof(TValue) * f->sizek + + sizeof(int) * f->sizelineinfo + + sizeof(LocVar) * f->sizelocvars + + sizeof(Upvaldesc) * f->sizeupvalues; +} + + +static lu_mem traverseCclosure (global_State *g, CClosure *cl) { + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return sizeCclosure(cl->nupvalues); +} + +static lu_mem traverseLclosure (global_State *g, LClosure *cl) { + int i; + markobject(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->upvals[i]); + return sizeLclosure(cl->nupvalues); +} + + +static lu_mem traversestack (global_State *g, lua_State *th) { + StkId o = th->stack; + if (o == NULL) + return 1; /* stack not completely built yet */ + for (; o < th->top; o++) + markvalue(g, o); + if (g->gcstate == GCSatomic) { /* final traversal? */ + StkId lim = th->stack + th->stacksize; /* real end of stack */ + for (; o < lim; o++) /* clear not-marked stack slice */ + setnilvalue(o); + } + return sizeof(lua_State) + sizeof(TValue) * th->stacksize; +} + + +/* +** traverse one gray object, turning it to black (except for threads, +** which are always gray). +*/ +static void propagatemark (global_State *g) { + lu_mem size; + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (gch(o)->tt) { + case LUA_TTABLE: { + Table *h = gco2t(o); + g->gray = h->gclist; /* remove from 'gray' list */ + size = traversetable(g, h); + break; + } + case LUA_TLCL: { + LClosure *cl = gco2lcl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseLclosure(g, cl); + break; + } + case LUA_TCCL: { + CClosure *cl = gco2ccl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseCclosure(g, cl); + break; + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; /* remove from 'gray' list */ + th->gclist = g->grayagain; + g->grayagain = o; /* insert into 'grayagain' list */ + black2gray(o); + size = traversestack(g, th); + break; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; /* remove from 'gray' list */ + size = traverseproto(g, p); + break; + } + default: lua_assert(0); return; + } + g->GCmemtrav += size; +} + + +static void propagateall (global_State *g) { + while (g->gray) propagatemark(g); +} + + +static void propagatelist (global_State *g, GCObject *l) { + lua_assert(g->gray == NULL); /* no grays left */ + g->gray = l; + propagateall(g); /* traverse all elements from 'l' */ +} + +/* +** retraverse all gray lists. Because tables may be reinserted in other +** lists when traversed, traverse the original lists to avoid traversing +** twice the same table (which is not wrong, but inefficient) +*/ +static void retraversegrays (global_State *g) { + GCObject *weak = g->weak; /* save original lists */ + GCObject *grayagain = g->grayagain; + GCObject *ephemeron = g->ephemeron; + g->weak = g->grayagain = g->ephemeron = NULL; + propagateall(g); /* traverse main gray list */ + propagatelist(g, grayagain); + propagatelist(g, weak); + propagatelist(g, ephemeron); +} + + +static void convergeephemerons (global_State *g) { + int changed; + do { + GCObject *w; + GCObject *next = g->ephemeron; /* get ephemeron list */ + g->ephemeron = NULL; /* tables will return to this list when traversed */ + changed = 0; + while ((w = next) != NULL) { + next = gco2t(w)->gclist; + if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ + propagateall(g); /* propagate changes */ + changed = 1; /* will have to revisit all ephemeron tables */ + } + } + } while (changed); +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Sweep Functions +** ======================================================= +*/ + + +/* +** clear entries with unmarked keys from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearkeys (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +/* +** clear entries with unmarked values from all weaktables in list 'l' up +** to element 'f' +*/ +static void clearvalues (global_State *g, GCObject *l, GCObject *f) { + for (; l != f; l = gco2t(l)->gclist) { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) { + TValue *o = &h->array[i]; + if (iscleared(g, o)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + for (n = gnode(h, 0); n < limit; n++) { + if (!ttisnil(gval(n)) && iscleared(g, gval(n))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (gch(o)->tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TLCL: { + luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); + break; + } + case LUA_TCCL: { + luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); + break; + } + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2t(o)); break; + case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; + case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; + case LUA_TSHRSTR: + G(L)->strt.nuse--; + /* go through */ + case LUA_TLNGSTR: { + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + default: lua_assert(0); + } +} + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); + + +/* +** sweep the (open) upvalues of a thread and resize its stack and +** list of call-info structures. +*/ +static void sweepthread (lua_State *L, lua_State *L1) { + if (L1->stack == NULL) return; /* stack not completely built yet */ + sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ + luaE_freeCI(L1); /* free extra CallInfo slots */ + /* should not change the stack during an emergency gc cycle */ + if (G(L)->gckind != KGC_EMERGENCY) + luaD_shrinkstack(L1); +} + + +/* +** sweep at most 'count' elements from a list of GCObjects erasing dead +** objects, where a dead (not alive) object is one marked with the "old" +** (non current) white and not fixed. +** In non-generational mode, change all non-dead objects back to white, +** preparing for next collection cycle. +** In generational mode, keep black objects black, and also mark them as +** old; stop when hitting an old object, as all objects after that +** one will be old too. +** When object is a thread, sweep its list of open upvalues too. +*/ +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + global_State *g = G(L); + int ow = otherwhite(g); + int toclear, toset; /* bits to clear and to set in all live objects */ + int tostop; /* stop sweep when this is true */ + if (isgenerational(g)) { /* generational mode? */ + toclear = ~0; /* clear nothing */ + toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ + tostop = bitmask(OLDBIT); /* do not sweep old generation */ + } + else { /* normal mode */ + toclear = maskcolors; /* clear all color bits + old bit */ + toset = luaC_white(g); /* make object white */ + tostop = 0; /* do not stop */ + } + while (*p != NULL && count-- > 0) { + GCObject *curr = *p; + int marked = gch(curr)->marked; + if (isdeadm(ow, marked)) { /* is 'curr' dead? */ + *p = gch(curr)->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else { + if (testbits(marked, tostop)) + return NULL; /* stop sweeping this list */ + if (gch(curr)->tt == LUA_TTHREAD) + sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ + /* update marks */ + gch(curr)->marked = cast_byte((marked & toclear) | toset); + p = &gch(curr)->next; /* go to next element */ + } + } + return (*p == NULL) ? NULL : p; +} + + +/* +** sweep a list until a live object (or end of list) +*/ +static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { + GCObject ** old = p; + int i = 0; + do { + i++; + p = sweeplist(L, p, 1); + } while (p == old); + if (n) *n += i; + return p; +} + +/* }====================================================== */ + + +/* +** {====================================================== +** Finalization +** ======================================================= +*/ + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ + int hs = g->strt.size / 2; /* half the size of the string table */ + if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ + luaS_resize(L, hs); /* halve its size */ + luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ + } +} + + +static GCObject *udata2finalize (global_State *g) { + GCObject *o = g->tobefnz; /* get first element */ + lua_assert(isfinalized(o)); + g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ + gch(o)->next = g->allgc; /* return it to 'allgc' list */ + g->allgc = o; + resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ + lua_assert(!isold(o)); /* see MOVE OLD rule */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + return o; +} + + +static void dothecall (lua_State *L, void *ud) { + UNUSED(ud); + luaD_call(L, L->top - 2, 0, 0); +} + + +static void GCTM (lua_State *L, int propagateerrors) { + global_State *g = G(L); + const TValue *tm; + TValue v; + setgcovalue(L, &v, udata2finalize(g)); + tm = luaT_gettmbyobj(L, &v, TM_GC); + if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; + int running = g->gcrunning; + L->allowhook = 0; /* stop debug hooks during GC metamethod */ + g->gcrunning = 0; /* avoid GC steps */ + setobj2s(L, L->top, tm); /* push finalizer... */ + setobj2s(L, L->top + 1, &v); /* ... and its argument */ + L->top += 2; /* and (next line) call the finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); + L->allowhook = oldah; /* restore hooks */ + g->gcrunning = running; /* restore state */ + if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ + if (status == LUA_ERRRUN) { /* is there an error object? */ + const char *msg = (ttisstring(L->top - 1)) + ? svalue(L->top - 1) + : "no message"; + luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); + status = LUA_ERRGCMM; /* error in __gc metamethod */ + } + luaD_throw(L, status); /* re-throw error */ + } + } +} + + +/* +** move all unreachable objects (or 'all' objects) that need +** finalization from list 'finobj' to list 'tobefnz' (to be finalized) +*/ +static void separatetobefnz (lua_State *L, int all) { + global_State *g = G(L); + GCObject **p = &g->finobj; + GCObject *curr; + GCObject **lastnext = &g->tobefnz; + /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ + while (*lastnext != NULL) + lastnext = &gch(*lastnext)->next; + while ((curr = *p) != NULL) { /* traverse all finalizable objects */ + lua_assert(!isfinalized(curr)); + lua_assert(testbit(gch(curr)->marked, SEPARATED)); + if (!(iswhite(curr) || all)) /* not being collected? */ + p = &gch(curr)->next; /* don't bother with it */ + else { + l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ + *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ + gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ + *lastnext = curr; + lastnext = &gch(curr)->next; + } + } +} + + +/* +** if object 'o' has a finalizer, remove it from 'allgc' list (must +** search the list to find it) and link it in 'finobj' list. +*/ +void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { + global_State *g = G(L); + if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ + isfinalized(o) || /* ... or is finalized... */ + gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ + return; /* nothing to be done */ + else { /* move 'o' to 'finobj' list */ + GCObject **p; + GCheader *ho = gch(o); + if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ + lua_assert(issweepphase(g)); + g->sweepgc = sweeptolive(L, g->sweepgc, NULL); + } + /* search for pointer pointing to 'o' */ + for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } + *p = ho->next; /* remove 'o' from root list */ + ho->next = g->finobj; /* link it in list 'finobj' */ + g->finobj = o; + l_setbit(ho->marked, SEPARATED); /* mark it as such */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + else + resetoldbit(o); /* see MOVE OLD rule */ + } +} + +/* }====================================================== */ + + +/* +** {====================================================== +** GC control +** ======================================================= +*/ + + +/* +** set a reasonable "time" to wait before starting a new GC cycle; +** cycle will start when memory use hits threshold +*/ +static void setpause (global_State *g, l_mem estimate) { + l_mem debt, threshold; + estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ + threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ + ? estimate * g->gcpause /* no overflow */ + : MAX_LMEM; /* overflow; truncate to maximum */ + debt = -cast(l_mem, threshold - gettotalbytes(g)); + luaE_setdebt(g, debt); +} + + +#define sweepphases \ + (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) + + +/* +** enter first sweep phase (strings) and prepare pointers for other +** sweep phases. The calls to 'sweeptolive' make pointers point to an +** object inside the list (instead of to the header), so that the real +** sweep do not need to skip objects created between "now" and the start +** of the real sweep. +** Returns how many objects it swept. +*/ +static int entersweep (lua_State *L) { + global_State *g = G(L); + int n = 0; + g->gcstate = GCSsweepstring; + lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); + /* prepare to sweep strings, finalizable objects, and regular objects */ + g->sweepstrgc = 0; + g->sweepfin = sweeptolive(L, &g->finobj, &n); + g->sweepgc = sweeptolive(L, &g->allgc, &n); + return n; +} + + +/* +** change GC mode +*/ +void luaC_changemode (lua_State *L, int mode) { + global_State *g = G(L); + if (mode == g->gckind) return; /* nothing to change */ + if (mode == KGC_GEN) { /* change to generational mode */ + /* make sure gray lists are consistent */ + luaC_runtilstate(L, bitmask(GCSpropagate)); + g->GCestimate = gettotalbytes(g); + g->gckind = KGC_GEN; + } + else { /* change to incremental mode */ + /* sweep all objects to turn them back to white + (as white has not changed, nothing extra will be collected) */ + g->gckind = KGC_NORMAL; + entersweep(L); + luaC_runtilstate(L, ~sweepphases); + } +} + + +/* +** call all pending finalizers +*/ +static void callallpendingfinalizers (lua_State *L, int propagateerrors) { + global_State *g = G(L); + while (g->tobefnz) { + resetoldbit(g->tobefnz); + GCTM(L, propagateerrors); + } +} + + +void luaC_freeallobjects (lua_State *L) { + global_State *g = G(L); + int i; + separatetobefnz(L, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); + callallpendingfinalizers(L, 0); + g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ + g->gckind = KGC_NORMAL; + sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ + sweepwholelist(L, &g->allgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); + lua_assert(g->strt.nuse == 0); +} + + +static l_mem atomic (lua_State *L) { + global_State *g = G(L); + l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ + GCObject *origweak, *origall; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + /* registry and global metatables may be changed by API */ + markvalue(g, &g->l_registry); + markmt(g); /* mark basic metatables */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + propagateall(g); /* propagate changes */ + work += g->GCmemtrav; /* stop counting (do not (re)count grays) */ + /* traverse objects caught by write barrier and by 'remarkupvals' */ + retraversegrays(g); + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all strongly accessible objects are marked. */ + /* clear values from weak tables, before checking finalizers */ + clearvalues(g, g->weak, NULL); + clearvalues(g, g->allweak, NULL); + origweak = g->weak; origall = g->allweak; + work += g->GCmemtrav; /* stop counting (objects being finalized) */ + separatetobefnz(L, 0); /* separate objects to be finalized */ + markbeingfnz(g); /* mark objects that will be finalized */ + propagateall(g); /* remark, to propagate `preserveness' */ + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all resurrected objects are marked. */ + /* remove dead objects from weak tables */ + clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ + clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */ + /* clear values from resurrected weak tables */ + clearvalues(g, g->weak, origweak); + clearvalues(g, g->allweak, origall); + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ + work += g->GCmemtrav; /* complete counting */ + return work; /* estimate of memory marked by 'atomic' */ +} + + +static lu_mem singlestep (lua_State *L) { global_State *g = G(L); - /*lua_checkmemory(L);*/ switch (g->gcstate) { case GCSpause: { - markroot(L); /* start a new collection */ - return 0; + /* start to count memory traversed */ + g->GCmemtrav = g->strt.size * sizeof(GCObject*); + lua_assert(!isgenerational(g)); + restartcollection(g); + g->gcstate = GCSpropagate; + return g->GCmemtrav; } case GCSpropagate: { - if (g->gray) - return propagatemark(g); + if (g->gray) { + lu_mem oldtrav = g->GCmemtrav; + propagatemark(g); + return g->GCmemtrav - oldtrav; /* memory traversed in this step */ + } else { /* no more `gray' objects */ - atomic(L); /* finish mark phase */ - return 0; + lu_mem work; + int sw; + g->gcstate = GCSatomic; /* finish mark phase */ + g->GCestimate = g->GCmemtrav; /* save what was counted */; + work = atomic(L); /* add what was traversed by 'atomic' */ + g->GCestimate += work; /* estimate of total memory traversed */ + sw = entersweep(L); + return work + sw * GCSWEEPCOST; } } case GCSsweepstring: { - lu_mem old = g->totalbytes; - sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); - if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ - g->gcstate = GCSsweep; /* end sweep-string phase */ - lua_assert(old >= g->totalbytes); - g->estimate -= old - g->totalbytes; - return GCSWEEPCOST; + int i; + for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) + sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); + g->sweepstrgc += i; + if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ + g->gcstate = GCSsweepudata; + return i * GCSWEEPCOST; } - case GCSsweep: { - lu_mem old = g->totalbytes; - g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); - if (*g->sweepgc == NULL) { /* nothing more to sweep? */ - checkSizes(L); - g->gcstate = GCSfinalize; /* end sweep phase */ - } - lua_assert(old >= g->totalbytes); - g->estimate -= old - g->totalbytes; - return GCSWEEPMAX*GCSWEEPCOST; - } - case GCSfinalize: { - if (g->tmudata) { - GCTM(L); - if (g->estimate > GCFINALIZECOST) - g->estimate -= GCFINALIZECOST; - return GCFINALIZECOST; + case GCSsweepudata: { + if (g->sweepfin) { + g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); + return GCSWEEPMAX*GCSWEEPCOST; } else { - g->gcstate = GCSpause; /* end collection */ - g->gcdept = 0; + g->gcstate = GCSsweep; return 0; } } + case GCSsweep: { + if (g->sweepgc) { + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + return GCSWEEPMAX*GCSWEEPCOST; + } + else { + /* sweep main thread */ + GCObject *mt = obj2gco(g->mainthread); + sweeplist(L, &mt, 1); + checkSizes(L); + g->gcstate = GCSpause; /* finish collection */ + return GCSWEEPCOST; + } + } default: lua_assert(0); return 0; } } -void luaC_step (lua_State *L) { +/* +** advances the garbage collector until it reaches a state allowed +** by 'statemask' +*/ +void luaC_runtilstate (lua_State *L, int statesmask) { global_State *g = G(L); - l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; - if (lim == 0) - lim = (MAX_LUMEM-1)/2; /* no limit */ - g->gcdept += g->totalbytes - g->GCthreshold; - do { - lim -= singlestep(L); - if (g->gcstate == GCSpause) - break; - } while (lim > 0); - if (g->gcstate != GCSpause) { - if (g->gcdept < GCSTEPSIZE) - g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ - else { - g->gcdept -= GCSTEPSIZE; - g->GCthreshold = g->totalbytes; - } + while (!testbit(statesmask, g->gcstate)) + singlestep(L); +} + + +static void generationalcollection (lua_State *L) { + global_State *g = G(L); + lua_assert(g->gcstate == GCSpropagate); + if (g->GCestimate == 0) { /* signal for another major collection? */ + luaC_fullgc(L, 0); /* perform a full regular collection */ + g->GCestimate = gettotalbytes(g); /* update control */ } else { - lua_assert(g->totalbytes >= g->estimate); - setthreshold(g); + lu_mem estimate = g->GCestimate; + luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */ + g->gcstate = GCSpropagate; /* skip restart */ + if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) + g->GCestimate = 0; /* signal for a major collection */ + else + g->GCestimate = estimate; /* keep estimate from last major coll. */ + + } + setpause(g, gettotalbytes(g)); + lua_assert(g->gcstate == GCSpropagate); +} + + +static void incstep (lua_State *L) { + global_State *g = G(L); + l_mem debt = g->GCdebt; + int stepmul = g->gcstepmul; + if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */ + /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ + debt = (debt / STEPMULADJ) + 1; + debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; + do { /* always perform at least one single step */ + lu_mem work = singlestep(L); /* do some work */ + debt -= work; + } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); + if (g->gcstate == GCSpause) + setpause(g, g->GCestimate); /* pause until next cycle */ + else { + debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ + luaE_setdebt(g, debt); } } -void luaC_fullgc (lua_State *L) { +/* +** performs a basic GC step +*/ +void luaC_forcestep (lua_State *L) { global_State *g = G(L); - if (g->gcstate <= GCSpropagate) { - /* reset sweep marks to sweep all elements (returning them to white) */ - g->sweepstrgc = 0; - g->sweepgc = &g->rootgc; - /* reset other collector lists */ - g->gray = NULL; - g->grayagain = NULL; - g->weak = NULL; - g->gcstate = GCSsweepstring; + int i; + if (isgenerational(g)) generationalcollection(L); + else incstep(L); + /* run a few finalizers (or all of them at the end of a collect cycle) */ + for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) + GCTM(L, 1); /* call one finalizer */ +} + + +/* +** performs a basic GC step only if collector is running +*/ +void luaC_step (lua_State *L) { + global_State *g = G(L); + if (g->gcrunning) luaC_forcestep(L); + else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ +} + + + +/* +** performs a full GC cycle; if "isemergency", does not call +** finalizers (which could change stack positions) +*/ +void luaC_fullgc (lua_State *L, int isemergency) { + global_State *g = G(L); + int origkind = g->gckind; + lua_assert(origkind != KGC_EMERGENCY); + if (isemergency) /* do not run finalizers during emergency GC */ + g->gckind = KGC_EMERGENCY; + else { + g->gckind = KGC_NORMAL; + callallpendingfinalizers(L, 1); } - lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); - /* finish any pending sweep phase */ - while (g->gcstate != GCSfinalize) { - lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); - singlestep(L); + if (keepinvariant(g)) { /* may there be some black objects? */ + /* must sweep all objects to turn them back to white + (as white has not changed, nothing will be collected) */ + entersweep(L); } - markroot(L); - while (g->gcstate != GCSpause) { - singlestep(L); + /* finish any pending sweep phase to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpause)); + luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ + luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ + if (origkind == KGC_GEN) { /* generational mode? */ + /* generational mode must be kept in propagate phase */ + luaC_runtilstate(L, bitmask(GCSpropagate)); } - setthreshold(g); + g->gckind = origkind; + setpause(g, gettotalbytes(g)); + if (!isemergency) /* do not run finalizers during emergency GC */ + callallpendingfinalizers(L, 1); } - -void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { - global_State *g = G(L); - lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); - lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); - lua_assert(ttype(&o->gch) != LUA_TTABLE); - /* must keep invariant? */ - if (g->gcstate == GCSpropagate) - reallymarkobject(g, v); /* restore invariant */ - else /* don't mind */ - makewhite(g, o); /* mark as white just to avoid other barriers */ -} +/* }====================================================== */ -void luaC_barrierback (lua_State *L, Table *t) { - global_State *g = G(L); - GCObject *o = obj2gco(t); - lua_assert(isblack(o) && !isdead(g, o)); - lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); - black2gray(o); /* make table gray (again) */ - t->gclist = g->grayagain; - g->grayagain = o; -} - - -void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { - global_State *g = G(L); - o->gch.next = g->rootgc; - g->rootgc = o; - o->gch.marked = luaC_white(g); - o->gch.tt = tt; -} - - -void luaC_linkupval (lua_State *L, UpVal *uv) { - global_State *g = G(L); - GCObject *o = obj2gco(uv); - o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ - g->rootgc = o; - if (isgray(o)) { - if (g->gcstate == GCSpropagate) { - gray2black(o); /* closed upvalues need barrier */ - luaC_barrier(L, uv, uv->v); - } - else { /* sweep phase: sweep it (turning it into white) */ - makewhite(g, o); - lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); - } - } -} - diff --git a/src/mod/languages/mod_lua/lua/lgc.h b/src/mod/languages/mod_lua/lua/lgc.h index 5a8dc605b3..dee270b4dc 100644 --- a/src/mod/languages/mod_lua/lua/lgc.h +++ b/src/mod/languages/mod_lua/lua/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lgc.h,v 2.58 2012/09/11 12:53:08 roberto Exp $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -9,65 +9,107 @@ #include "lobject.h" +#include "lstate.h" + +/* +** Collectable objects may have one of three colors: white, which +** means the object is not marked; gray, which means the +** object is marked, but its references may be not marked; and +** black, which means that the object and all its references are marked. +** The main invariant of the garbage collector, while marking objects, +** is that a black object can never point to a white one. Moreover, +** any gray object must be in a "gray list" (gray, grayagain, weak, +** allweak, ephemeron) so that it can be visited again before finishing +** the collection cycle. These lists have no meaning when the invariant +** is not being enforced (e.g., sweep phase). +*/ + + + +/* how much to allocate before next GC step */ +#if !defined(GCSTEPSIZE) +/* ~100 small strings */ +#define GCSTEPSIZE (cast_int(100 * sizeof(TString))) +#endif /* ** Possible states of the Garbage Collector */ -#define GCSpause 0 -#define GCSpropagate 1 +#define GCSpropagate 0 +#define GCSatomic 1 #define GCSsweepstring 2 -#define GCSsweep 3 -#define GCSfinalize 4 +#define GCSsweepudata 3 +#define GCSsweep 4 +#define GCSpause 5 + + +#define issweepphase(g) \ + (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) + +#define isgenerational(g) ((g)->gckind == KGC_GEN) + +/* +** macros to tell when main invariant (white objects cannot point to black +** ones) must be kept. During a non-generational collection, the sweep +** phase may break the invariant, as objects turned white may point to +** still-black objects. The invariant is restored when sweep ends and +** all objects are white again. During a generational collection, the +** invariant must be kept all times. +*/ + +#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) /* -** some userful bit tricks +** Outside the collector, the state in generational mode is kept in +** 'propagate', so 'keepinvariant' is always true. */ -#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) -#define setbits(x,m) ((x) |= (m)) -#define testbits(x,m) ((x) & (m)) -#define bitmask(b) (1<<(b)) -#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) -#define l_setbit(x,b) setbits(x, bitmask(b)) -#define resetbit(x,b) resetbits(x, bitmask(b)) -#define testbit(x,b) testbits(x, bitmask(b)) -#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) -#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) -#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) - +#define keepinvariantout(g) \ + check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ + g->gcstate <= GCSatomic) /* -** Layout for bit use in `marked' field: -** bit 0 - object is white (type 0) -** bit 1 - object is white (type 1) -** bit 2 - object is black -** bit 3 - for userdata: has been finalized -** bit 3 - for tables: has weak keys -** bit 4 - for tables: has weak values -** bit 5 - object is fixed (should not be collected) -** bit 6 - object is "super" fixed (only the main thread) +** some useful bit tricks */ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) -#define WHITE0BIT 0 -#define WHITE1BIT 1 -#define BLACKBIT 2 -#define FINALIZEDBIT 3 -#define KEYWEAKBIT 3 -#define VALUEWEAKBIT 4 -#define FIXEDBIT 5 -#define SFIXEDBIT 6 +/* Layout for bit use in `marked' field: */ +#define WHITE0BIT 0 /* object is white (type 0) */ +#define WHITE1BIT 1 /* object is white (type 1) */ +#define BLACKBIT 2 /* object is black */ +#define FINALIZEDBIT 3 /* object has been separated for finalization */ +#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ +#define FIXEDBIT 5 /* object is fixed (should not be collected) */ +#define OLDBIT 6 /* object is old (only in generational mode) */ +/* bit 7 is currently used by tests (luaL_checkmemory) */ + #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) -#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define iswhite(x) testbits((x)->gch.marked, WHITEBITS) #define isblack(x) testbit((x)->gch.marked, BLACKBIT) -#define isgray(x) (!isblack(x) && !iswhite(x)) +#define isgray(x) /* neither white nor black */ \ + (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) + +#define isold(x) testbit((x)->gch.marked, OLDBIT) + +/* MOVE OLD rule: whenever an object is moved to the beginning of + a GC list, its old bit must be cleared */ +#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) #define otherwhite(g) (g->currentwhite ^ WHITEBITS) -#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) +#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) +#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) @@ -77,34 +119,39 @@ #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) -#define luaC_checkGC(L) { \ - condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ - if (G(L)->totalbytes >= G(L)->GCthreshold) \ - luaC_step(L); } +#define luaC_condGC(L,c) \ + {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} +#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ - luaC_barrierf(L,obj2gco(p),gcvalue(v)); } + luaC_barrier_(L,obj2gco(p),gcvalue(v)); } -#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ - luaC_barrierback(L,t); } +#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierback_(L,p); } #define luaC_objbarrier(L,p,o) \ { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ - luaC_barrierf(L,obj2gco(p),obj2gco(o)); } + luaC_barrier_(L,obj2gco(p),obj2gco(o)); } -#define luaC_objbarriert(L,t,o) \ - { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } +#define luaC_objbarrierback(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } -LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); -LUAI_FUNC void luaC_callGCTM (lua_State *L); -LUAI_FUNC void luaC_freeall (lua_State *L); +#define luaC_barrierproto(L,p,c) \ + { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } + +LUAI_FUNC void luaC_freeallobjects (lua_State *L); LUAI_FUNC void luaC_step (lua_State *L); -LUAI_FUNC void luaC_fullgc (lua_State *L); -LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); -LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); -LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); -LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); - +LUAI_FUNC void luaC_forcestep (lua_State *L); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, + GCObject **list, int offset); +LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); +LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); +LUAI_FUNC void luaC_changemode (lua_State *L, int mode); #endif diff --git a/src/mod/languages/mod_lua/lua/linit.c b/src/mod/languages/mod_lua/lua/linit.c index c1f90dfab7..8d3aa6576f 100644 --- a/src/mod/languages/mod_lua/lua/linit.c +++ b/src/mod/languages/mod_lua/lua/linit.c @@ -1,10 +1,18 @@ /* -** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ -** Initialization of libraries for lua.c +** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $ +** Initialization of libraries for lua.c and other clients ** See Copyright Notice in lua.h */ +/* +** If you embed Lua in your program and need to open the standard +** libraries, call luaL_openlibs in your program. If you need a +** different set of libraries, copy this file to your project and edit +** it to suit your needs. +*/ + + #define linit_c #define LUA_LIB @@ -14,25 +22,46 @@ #include "lauxlib.h" -static const luaL_Reg lualibs[] = { - {"", luaopen_base}, +/* +** these libs are loaded by lua.c and are readily available to any Lua +** program +*/ +static const luaL_Reg loadedlibs[] = { + {"_G", luaopen_base}, {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, {LUA_TABLIBNAME, luaopen_table}, {LUA_IOLIBNAME, luaopen_io}, {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, + {LUA_BITLIBNAME, luaopen_bit32}, {LUA_MATHLIBNAME, luaopen_math}, {LUA_DBLIBNAME, luaopen_debug}, {NULL, NULL} }; +/* +** these libs are preloaded and must be required before used +*/ +static const luaL_Reg preloadedlibs[] = { + {NULL, NULL} +}; + + LUALIB_API void luaL_openlibs (lua_State *L) { - const luaL_Reg *lib = lualibs; - for (; lib->func; lib++) { - lua_pushcfunction(L, lib->func); - lua_pushstring(L, lib->name); - lua_call(L, 1, 0); + const luaL_Reg *lib; + /* call open functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ } + /* add open functions from 'preloadedlibs' into 'package.preload' table */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + for (lib = preloadedlibs; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_setfield(L, -2, lib->name); + } + lua_pop(L, 1); /* remove _PRELOAD table */ } diff --git a/src/mod/languages/mod_lua/lua/liolib.c b/src/mod/languages/mod_lua/lua/liolib.c index e79ed1cb2e..3f80db1927 100644 --- a/src/mod/languages/mod_lua/lua/liolib.c +++ b/src/mod/languages/mod_lua/lua/liolib.c @@ -1,10 +1,20 @@ /* -** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ +** $Id: liolib.c,v 2.111 2013/03/21 13:57:27 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ +/* +** POSIX idiosyncrasy! +** This definition must come before the inclusion of 'stdio.h'; it +** should not affect non-POSIX systems +*/ +#if !defined(_FILE_OFFSET_BITS) +#define _FILE_OFFSET_BITS 64 +#endif + + #include #include #include @@ -19,49 +29,110 @@ #include "lualib.h" +#if !defined(lua_checkmode) -#define IO_INPUT 1 -#define IO_OUTPUT 2 +/* +** Check whether 'mode' matches '[rwa]%+?b?'. +** Change this macro to accept other modes for 'fopen' besides +** the standard ones. +*/ +#define lua_checkmode(mode) \ + (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ + (*mode != '+' || ++mode) && /* skip if char is '+' */ \ + (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ + (*mode == '\0')) + +#endif + +/* +** {====================================================== +** lua_popen spawns a new process connected to the current +** one through the file streams. +** ======================================================= +*/ + +#if !defined(lua_popen) /* { */ + +#if defined(LUA_USE_POPEN) /* { */ + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, pclose(file)) + +#elif defined(LUA_WIN) /* }{ */ + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, _pclose(file)) -static const char *const fnames[] = {"input", "output"}; +#else /* }{ */ + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), -1) -static int pushresult (lua_State *L, int i, const char *filename) { - int en = errno; /* calls to Lua API may change this value */ - if (i) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushnil(L); - if (filename) - lua_pushfstring(L, "%s: %s", filename, strerror(en)); - else - lua_pushfstring(L, "%s", strerror(en)); - lua_pushinteger(L, en); - return 3; - } -} +#endif /* } */ + +#endif /* } */ + +/* }====================================================== */ -static void fileerror (lua_State *L, int arg, const char *filename) { - lua_pushfstring(L, "%s: %s", filename, strerror(errno)); - luaL_argerror(L, arg, lua_tostring(L, -1)); -} +/* +** {====================================================== +** lua_fseek/lua_ftell: configuration for longer offsets +** ======================================================= +*/ + +#if !defined(lua_fseek) /* { */ + +#if defined(LUA_USE_POSIX) + +#define l_fseek(f,o,w) fseeko(f,o,w) +#define l_ftell(f) ftello(f) +#define l_seeknum off_t + +#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \ + && defined(_MSC_VER) && (_MSC_VER >= 1400) +/* Windows (but not DDK) and Visual C++ 2005 or higher */ + +#define l_fseek(f,o,w) _fseeki64(f,o,w) +#define l_ftell(f) _ftelli64(f) +#define l_seeknum __int64 + +#else + +#define l_fseek(f,o,w) fseek(f,o,w) +#define l_ftell(f) ftell(f) +#define l_seeknum long + +#endif + +#endif /* } */ + +/* }====================================================== */ -#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) +#define IO_PREFIX "_IO_" +#define IO_INPUT (IO_PREFIX "input") +#define IO_OUTPUT (IO_PREFIX "output") + + +typedef luaL_Stream LStream; + + +#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + +#define isclosed(p) ((p)->closef == NULL) static int io_type (lua_State *L) { - void *ud; + LStream *p; luaL_checkany(L, 1); - ud = lua_touserdata(L, 1); - lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); - if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); + if (p == NULL) lua_pushnil(L); /* not a file */ - else if (*((FILE **)ud) == NULL) + else if (isclosed(p)) lua_pushliteral(L, "closed file"); else lua_pushliteral(L, "file"); @@ -69,47 +140,59 @@ static int io_type (lua_State *L) { } -static FILE *tofile (lua_State *L) { - FILE **f = tofilep(L); - if (*f == NULL) - luaL_error(L, "attempt to use a closed file"); - return *f; +static int f_tostring (lua_State *L) { + LStream *p = tolstream(L); + if (isclosed(p)) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", p->f); + return 1; } +static FILE *tofile (lua_State *L) { + LStream *p = tolstream(L); + if (isclosed(p)) + luaL_error(L, "attempt to use a closed file"); + lua_assert(p->f); + return p->f; +} + /* ** When creating file handles, always creates a `closed' file handle ** before opening the actual file; so, if there is a memory error, the ** file is not left opened. */ -static FILE **newfile (lua_State *L) { - FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); - *pf = NULL; /* file handle is currently `closed' */ - luaL_getmetatable(L, LUA_FILEHANDLE); - lua_setmetatable(L, -2); - return pf; +static LStream *newprefile (lua_State *L) { + LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); + p->closef = NULL; /* mark file handle as 'closed' */ + luaL_setmetatable(L, LUA_FILEHANDLE); + return p; } -/* -** function to (not) close the standard files stdin, stdout, and stderr -*/ -static int io_noclose (lua_State *L) { - lua_pushnil(L); - lua_pushliteral(L, "cannot close standard file"); - return 2; +static int aux_close (lua_State *L) { + LStream *p = tolstream(L); + lua_CFunction cf = p->closef; + p->closef = NULL; /* mark stream as closed */ + return (*cf)(L); /* close it */ } -/* -** function to close 'popen' files -*/ -static int io_pclose (lua_State *L) { - FILE **p = tofilep(L); - int ok = lua_pclose(L, *p); - *p = NULL; - return pushresult(L, ok, NULL); +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) /* no argument? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ + tofile(L); /* make sure argument is an open stream */ + return aux_close(L); +} + + +static int f_gc (lua_State *L) { + LStream *p = tolstream(L); + if (!isclosed(p) && p->f != NULL) + aux_close(L); /* ignore closed and incompletely open files */ + return 0; } @@ -117,103 +200,88 @@ static int io_pclose (lua_State *L) { ** function to close regular files */ static int io_fclose (lua_State *L) { - FILE **p = tofilep(L); - int ok = (fclose(*p) == 0); - *p = NULL; - return pushresult(L, ok, NULL); + LStream *p = tolstream(L); + int res = fclose(p->f); + return luaL_fileresult(L, (res == 0), NULL); } -static int aux_close (lua_State *L) { - lua_getfenv(L, 1); - lua_getfield(L, -1, "__close"); - return (lua_tocfunction(L, -1))(L); +static LStream *newfile (lua_State *L) { + LStream *p = newprefile(L); + p->f = NULL; + p->closef = &io_fclose; + return p; } -static int io_close (lua_State *L) { - if (lua_isnone(L, 1)) - lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); - tofile(L); /* make sure argument is a file */ - return aux_close(L); -} - - -static int io_gc (lua_State *L) { - FILE *f = *tofilep(L); - /* ignore closed files */ - if (f != NULL) - aux_close(L); - return 0; -} - - -static int io_tostring (lua_State *L) { - FILE *f = *tofilep(L); - if (f == NULL) - lua_pushliteral(L, "file (closed)"); - else - lua_pushfstring(L, "file (%p)", f); - return 1; +static void opencheck (lua_State *L, const char *fname, const char *mode) { + LStream *p = newfile(L); + p->f = fopen(fname, mode); + if (p->f == NULL) + luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); } static int io_open (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); - FILE **pf = newfile(L); - *pf = fopen(filename, mode); - return (*pf == NULL) ? pushresult(L, 0, filename) : 1; + LStream *p = newfile(L); + const char *md = mode; /* to traverse/check mode */ + luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); + p->f = fopen(filename, mode); + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; } /* -** this function has a separated environment, which defines the -** correct __close for 'popen' files +** function to close 'popen' files */ +static int io_pclose (lua_State *L) { + LStream *p = tolstream(L); + return luaL_execresult(L, lua_pclose(L, p->f)); +} + + static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); - FILE **pf = newfile(L); - *pf = lua_popen(L, filename, mode); - return (*pf == NULL) ? pushresult(L, 0, filename) : 1; + LStream *p = newprefile(L); + p->f = lua_popen(L, filename, mode); + p->closef = &io_pclose; + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; } static int io_tmpfile (lua_State *L) { - FILE **pf = newfile(L); - *pf = tmpfile(); - return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; + LStream *p = newfile(L); + p->f = tmpfile(); + return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; } -static FILE *getiofile (lua_State *L, int findex) { - FILE *f; - lua_rawgeti(L, LUA_ENVIRONINDEX, findex); - f = *(FILE **)lua_touserdata(L, -1); - if (f == NULL) - luaL_error(L, "standard %s file is closed", fnames[findex - 1]); - return f; +static FILE *getiofile (lua_State *L, const char *findex) { + LStream *p; + lua_getfield(L, LUA_REGISTRYINDEX, findex); + p = (LStream *)lua_touserdata(L, -1); + if (isclosed(p)) + luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX)); + return p->f; } -static int g_iofile (lua_State *L, int f, const char *mode) { +static int g_iofile (lua_State *L, const char *f, const char *mode) { if (!lua_isnoneornil(L, 1)) { const char *filename = lua_tostring(L, 1); - if (filename) { - FILE **pf = newfile(L); - *pf = fopen(filename, mode); - if (*pf == NULL) - fileerror(L, 1, filename); - } + if (filename) + opencheck(L, filename, mode); else { tofile(L); /* check that it's a valid file handle */ lua_pushvalue(L, 1); } - lua_rawseti(L, LUA_ENVIRONINDEX, f); + lua_setfield(L, LUA_REGISTRYINDEX, f); } /* return current value */ - lua_rawgeti(L, LUA_ENVIRONINDEX, f); + lua_getfield(L, LUA_REGISTRYINDEX, f); return 1; } @@ -231,35 +299,43 @@ static int io_output (lua_State *L) { static int io_readline (lua_State *L); -static void aux_lines (lua_State *L, int idx, int toclose) { - lua_pushvalue(L, idx); +static void aux_lines (lua_State *L, int toclose) { + int i; + int n = lua_gettop(L) - 1; /* number of arguments to read */ + /* ensure that arguments will fit here and into 'io_readline' stack */ + luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); + lua_pushvalue(L, 1); /* file handle */ + lua_pushinteger(L, n); /* number of arguments to read */ lua_pushboolean(L, toclose); /* close/not close file when finished */ - lua_pushcclosure(L, io_readline, 2); + for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ + lua_pushcclosure(L, io_readline, 3 + n); } static int f_lines (lua_State *L) { tofile(L); /* check that it's a valid file handle */ - aux_lines(L, 1, 0); + aux_lines(L, 0); return 1; } static int io_lines (lua_State *L) { - if (lua_isnoneornil(L, 1)) { /* no arguments? */ - /* will iterate over default input */ - lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); - return f_lines(L); + int toclose; + if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ + if (lua_isnil(L, 1)) { /* no file name? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ + lua_replace(L, 1); /* put it at index 1 */ + tofile(L); /* check that it's a valid file handle */ + toclose = 0; /* do not close it after iteration */ } - else { + else { /* open a new file */ const char *filename = luaL_checkstring(L, 1); - FILE **pf = newfile(L); - *pf = fopen(filename, "r"); - if (*pf == NULL) - fileerror(L, 1, filename); - aux_lines(L, lua_gettop(L), 1); - return 1; + opencheck(L, filename, "r"); + lua_replace(L, 1); /* put file at index 1 */ + toclose = 1; /* close it after iteration */ } + aux_lines(L, toclose); + return 1; } @@ -276,7 +352,10 @@ static int read_number (lua_State *L, FILE *f) { lua_pushnumber(L, d); return 1; } - else return 0; /* read fails */ + else { + lua_pushnil(L); /* "result" to be removed */ + return 0; /* read fails */ + } } @@ -288,7 +367,7 @@ static int test_eof (lua_State *L, FILE *f) { } -static int read_line (lua_State *L, FILE *f) { +static int read_line (lua_State *L, FILE *f, int chop) { luaL_Buffer b; luaL_buffinit(L, &b); for (;;) { @@ -296,13 +375,13 @@ static int read_line (lua_State *L, FILE *f) { char *p = luaL_prepbuffer(&b); if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ luaL_pushresult(&b); /* close buffer */ - return (lua_objlen(L, -1) > 0); /* check whether read something */ + return (lua_rawlen(L, -1) > 0); /* check whether read something */ } l = strlen(p); if (l == 0 || p[l-1] != '\n') luaL_addsize(&b, l); else { - luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ luaL_pushresult(&b); /* close buffer */ return 1; /* read at least an `eol' */ } @@ -310,21 +389,34 @@ static int read_line (lua_State *L, FILE *f) { } -static int read_chars (lua_State *L, FILE *f, size_t n) { - size_t rlen; /* how much to read */ - size_t nr; /* number of chars actually read */ +#define MAX_SIZE_T (~(size_t)0) + +static void read_all (lua_State *L, FILE *f) { + size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */ luaL_Buffer b; luaL_buffinit(L, &b); - rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ - do { - char *p = luaL_prepbuffer(&b); - if (rlen > n) rlen = n; /* cannot read more than asked */ - nr = fread(p, sizeof(char), rlen, f); + for (;;) { + char *p = luaL_prepbuffsize(&b, rlen); + size_t nr = fread(p, sizeof(char), rlen, f); luaL_addsize(&b, nr); - n -= nr; /* still have to read `n' chars */ - } while (n > 0 && nr == rlen); /* until end of count or eof */ + if (nr < rlen) break; /* eof? */ + else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */ + rlen *= 2; /* double buffer size at each iteration */ + } luaL_pushresult(&b); /* close buffer */ - return (n == 0 || lua_objlen(L, -1) > 0); +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t nr; /* number of chars actually read */ + char *p; + luaL_Buffer b; + luaL_buffinit(L, &b); + p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ + nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ + luaL_addsize(&b, nr); + luaL_pushresult(&b); /* close buffer */ + return (nr > 0); /* true iff read something */ } @@ -334,7 +426,7 @@ static int g_read (lua_State *L, FILE *f, int first) { int n; clearerr(f); if (nargs == 0) { /* no arguments? */ - success = read_line(L, f); + success = read_line(L, f, 1); n = first+1; /* to return 1 result */ } else { /* ensure stack space for all results and for auxlib's buffer */ @@ -353,10 +445,13 @@ static int g_read (lua_State *L, FILE *f, int first) { success = read_number(L, f); break; case 'l': /* line */ - success = read_line(L, f); + success = read_line(L, f, 1); + break; + case 'L': /* line with end-of-line */ + success = read_line(L, f, 0); break; case 'a': /* file */ - read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + read_all(L, f); /* read entire file */ success = 1; /* always success */ break; default: @@ -366,7 +461,7 @@ static int g_read (lua_State *L, FILE *f, int first) { } } if (ferror(f)) - return pushresult(L, 0, NULL); + return luaL_fileresult(L, 0, NULL); if (!success) { lua_pop(L, 1); /* remove last result */ lua_pushnil(L); /* push nil instead */ @@ -386,16 +481,24 @@ static int f_read (lua_State *L) { static int io_readline (lua_State *L) { - FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); - int sucess; - if (f == NULL) /* file is already closed? */ - luaL_error(L, "file is already closed"); - sucess = read_line(L, f); - if (ferror(f)) - return luaL_error(L, "%s", strerror(errno)); - if (sucess) return 1; - else { /* EOF */ - if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); + int i; + int n = (int)lua_tointeger(L, lua_upvalueindex(2)); + if (isclosed(p)) /* file is already closed? */ + return luaL_error(L, "file is already closed"); + lua_settop(L , 1); + for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ + lua_pushvalue(L, lua_upvalueindex(3 + i)); + n = g_read(L, p->f, 2); /* 'n' is number of results */ + lua_assert(n > 0); /* should return at least a nil */ + if (!lua_isnil(L, -n)) /* read at least one value? */ + return n; /* return them */ + else { /* first result is nil: EOF or error */ + if (n > 1) { /* is there error information? */ + /* 2nd result is error message */ + return luaL_error(L, "%s", lua_tostring(L, -n + 1)); + } + if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ lua_settop(L, 0); lua_pushvalue(L, lua_upvalueindex(1)); aux_close(L); /* close it */ @@ -408,7 +511,7 @@ static int io_readline (lua_State *L) { static int g_write (lua_State *L, FILE *f, int arg) { - int nargs = lua_gettop(L) - 1; + int nargs = lua_gettop(L) - arg; int status = 1; for (; nargs--; arg++) { if (lua_type(L, arg) == LUA_TNUMBER) { @@ -422,7 +525,8 @@ static int g_write (lua_State *L, FILE *f, int arg) { status = status && (fwrite(s, sizeof(char), l, f) == l); } } - return pushresult(L, status, NULL); + if (status) return 1; /* file handle already on stack top */ + else return luaL_fileresult(L, status, NULL); } @@ -432,7 +536,9 @@ static int io_write (lua_State *L) { static int f_write (lua_State *L) { - return g_write(L, tofile(L), 2); + FILE *f = tofile(L); + lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ + return g_write(L, f, 2); } @@ -441,12 +547,15 @@ static int f_seek (lua_State *L) { static const char *const modenames[] = {"set", "cur", "end", NULL}; FILE *f = tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); - long offset = luaL_optlong(L, 3, 0); - op = fseek(f, offset, mode[op]); + lua_Number p3 = luaL_optnumber(L, 3, 0); + l_seeknum offset = (l_seeknum)p3; + luaL_argcheck(L, (lua_Number)offset == p3, 3, + "not an integer in proper range"); + op = l_fseek(f, offset, mode[op]); if (op) - return pushresult(L, 0, NULL); /* error */ + return luaL_fileresult(L, 0, NULL); /* error */ else { - lua_pushinteger(L, ftell(f)); + lua_pushnumber(L, (lua_Number)l_ftell(f)); return 1; } } @@ -459,21 +568,24 @@ static int f_setvbuf (lua_State *L) { int op = luaL_checkoption(L, 2, NULL, modenames); lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); int res = setvbuf(f, NULL, mode[op], sz); - return pushresult(L, res == 0, NULL); + return luaL_fileresult(L, res == 0, NULL); } static int io_flush (lua_State *L) { - return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); + return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); } static int f_flush (lua_State *L) { - return pushresult(L, fflush(tofile(L)) == 0, NULL); + return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); } +/* +** functions for 'io' library +*/ static const luaL_Reg iolib[] = { {"close", io_close}, {"flush", io_flush}, @@ -490,6 +602,9 @@ static const luaL_Reg iolib[] = { }; +/* +** methods for file handles +*/ static const luaL_Reg flib[] = { {"close", io_close}, {"flush", f_flush}, @@ -498,8 +613,8 @@ static const luaL_Reg flib[] = { {"seek", f_seek}, {"setvbuf", f_setvbuf}, {"write", f_write}, - {"__gc", io_gc}, - {"__tostring", io_tostring}, + {"__gc", f_gc}, + {"__tostring", f_tostring}, {NULL, NULL} }; @@ -508,46 +623,43 @@ static void createmeta (lua_State *L) { luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ lua_pushvalue(L, -1); /* push metatable */ lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_register(L, NULL, flib); /* file methods */ + luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ + lua_pop(L, 1); /* pop new metatable */ } -static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { - *newfile(L) = f; - if (k > 0) { +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + LStream *p = tolstream(L); + p->closef = &io_noclose; /* keep file opened */ + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +static void createstdfile (lua_State *L, FILE *f, const char *k, + const char *fname) { + LStream *p = newprefile(L); + p->f = f; + p->closef = &io_noclose; + if (k != NULL) { lua_pushvalue(L, -1); - lua_rawseti(L, LUA_ENVIRONINDEX, k); + lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ } - lua_pushvalue(L, -2); /* copy environment */ - lua_setfenv(L, -2); /* set it */ - lua_setfield(L, -3, fname); + lua_setfield(L, -2, fname); /* add file to module */ } -static void newfenv (lua_State *L, lua_CFunction cls) { - lua_createtable(L, 0, 1); - lua_pushcfunction(L, cls); - lua_setfield(L, -2, "__close"); -} - - -LUALIB_API int luaopen_io (lua_State *L) { +LUAMOD_API int luaopen_io (lua_State *L) { + luaL_newlib(L, iolib); /* new module */ createmeta(L); - /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ - newfenv(L, io_fclose); - lua_replace(L, LUA_ENVIRONINDEX); - /* open library */ - luaL_register(L, LUA_IOLIBNAME, iolib); /* create (and set) default files */ - newfenv(L, io_noclose); /* close function for default files */ createstdfile(L, stdin, IO_INPUT, "stdin"); createstdfile(L, stdout, IO_OUTPUT, "stdout"); - createstdfile(L, stderr, 0, "stderr"); - lua_pop(L, 1); /* pop environment for default files */ - lua_getfield(L, -1, "popen"); - newfenv(L, io_pclose); /* create environment for 'popen' */ - lua_setfenv(L, -2); /* set fenv for 'popen' */ - lua_pop(L, 1); /* pop 'popen' */ + createstdfile(L, stderr, NULL, "stderr"); return 1; } diff --git a/src/mod/languages/mod_lua/lua/llex.c b/src/mod/languages/mod_lua/lua/llex.c index 6dc319358c..1a32e348b0 100644 --- a/src/mod/languages/mod_lua/lua/llex.c +++ b/src/mod/languages/mod_lua/lua/llex.c @@ -1,11 +1,10 @@ /* -** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: llex.c,v 2.63 2013/03/16 21:10:18 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ -#include #include #include @@ -14,6 +13,7 @@ #include "lua.h" +#include "lctype.h" #include "ldo.h" #include "llex.h" #include "lobject.h" @@ -29,35 +29,36 @@ - #define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') /* ORDER RESERVED */ -const char *const luaX_tokens [] = { +static const char *const luaX_tokens [] = { "and", "break", "do", "else", "elseif", - "end", "false", "for", "function", "if", + "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", - "..", "...", "==", ">=", "<=", "~=", - "", "", "", "", - NULL + "..", "...", "==", ">=", "<=", "~=", "::", "", + "", "", "" }; #define save_and_next(ls) (save(ls, ls->current), next(ls)) +static l_noret lexerror (LexState *ls, const char *msg, int token); + + static void save (LexState *ls, int c) { Mbuffer *b = ls->buff; - if (b->n + 1 > b->buffsize) { + if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { size_t newsize; - if (b->buffsize >= MAX_SIZET/2) - luaX_lexerror(ls, "lexical element too long", 0); - newsize = b->buffsize * 2; + if (luaZ_sizebuffer(b) >= MAX_SIZET/2) + lexerror(ls, "lexical element too long", 0); + newsize = luaZ_sizebuffer(b) * 2; luaZ_resizebuffer(ls->L, b, newsize); } - b->buffer[b->n++] = cast(char, c); + b->buffer[luaZ_bufflen(b)++] = cast(char, c); } @@ -66,23 +67,24 @@ void luaX_init (lua_State *L) { for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ + ts->tsv.extra = cast_byte(i+1); /* reserved word */ } } -#define MAXSRC 80 - - const char *luaX_token2str (LexState *ls, int token) { - if (token < FIRST_RESERVED) { + if (token < FIRST_RESERVED) { /* single-byte symbols? */ lua_assert(token == cast(unsigned char, token)); - return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : - luaO_pushfstring(ls->L, "%c", token); + return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : + luaO_pushfstring(ls->L, "char(%d)", token); + } + else { + const char *s = luaX_tokens[token - FIRST_RESERVED]; + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return luaO_pushfstring(ls->L, LUA_QS, s); + else /* names, strings, and numerals */ + return s; } - else - return luaX_tokens[token-FIRST_RESERVED]; } @@ -92,38 +94,54 @@ static const char *txtToken (LexState *ls, int token) { case TK_STRING: case TK_NUMBER: save(ls, '\0'); - return luaZ_buffer(ls->buff); + return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); default: return luaX_token2str(ls, token); } } -void luaX_lexerror (LexState *ls, const char *msg, int token) { - char buff[MAXSRC]; - luaO_chunkid(buff, getstr(ls->source), MAXSRC); +static l_noret lexerror (LexState *ls, const char *msg, int token) { + char buff[LUA_IDSIZE]; + luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE); msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); if (token) - luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); + luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); luaD_throw(ls->L, LUA_ERRSYNTAX); } -void luaX_syntaxerror (LexState *ls, const char *msg) { - luaX_lexerror(ls, msg, ls->t.token); +l_noret luaX_syntaxerror (LexState *ls, const char *msg) { + lexerror(ls, msg, ls->t.token); } +/* +** creates a new string and anchors it in function's table so that +** it will not be collected until the end of the function's compilation +** (by that time it should be anchored in function's prototype) +*/ TString *luaX_newstring (LexState *ls, const char *str, size_t l) { lua_State *L = ls->L; - TString *ts = luaS_newlstr(L, str, l); - TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ - if (ttisnil(o)) - setbvalue(o, 1); /* make sure `str' will not be collected */ + TValue *o; /* entry for `str' */ + TString *ts = luaS_newlstr(L, str, l); /* create new string */ + setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ + o = luaH_set(L, ls->fs->h, L->top - 1); + if (ttisnil(o)) { /* not in use yet? (see 'addK') */ + /* boolean value does not need GC barrier; + table has no metatable, so it does not need to invalidate cache */ + setbvalue(o, 1); /* t[string] = true */ + luaC_checkGC(L); + } + L->top--; /* remove string from stack */ return ts; } +/* +** increment line number and skips newline sequence (any of +** \n, \r, \n\r, or \r\n) +*/ static void inclinenumber (LexState *ls) { int old = ls->current; lua_assert(currIsNewline(ls)); @@ -135,17 +153,20 @@ static void inclinenumber (LexState *ls) { } -void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, + int firstchar) { ls->decpoint = '.'; ls->L = L; + ls->current = firstchar; ls->lookahead.token = TK_EOS; /* no look-ahead token */ ls->z = z; ls->fs = NULL; ls->linenumber = 1; ls->lastline = 1; ls->source = source; + ls->envn = luaS_new(L, LUA_ENV); /* create env name */ + luaS_fix(ls->envn); /* never collect this name */ luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ - next(ls); /* read first char */ } @@ -159,13 +180,16 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { static int check_next (LexState *ls, const char *set) { - if (!strchr(set, ls->current)) + if (ls->current == '\0' || !strchr(set, ls->current)) return 0; save_and_next(ls); return 1; } +/* +** change all characters 'from' in buffer to 'to' +*/ static void buffreplace (LexState *ls, char from, char to) { size_t n = luaZ_bufflen(ls->buff); char *p = luaZ_buffer(ls->buff); @@ -174,37 +198,59 @@ static void buffreplace (LexState *ls, char from, char to) { } +#if !defined(getlocaledecpoint) +#define getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + + +#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) + +/* +** in case of format error, try to change decimal point separator to +** the one defined in the current locale and check again +*/ static void trydecpoint (LexState *ls, SemInfo *seminfo) { - /* format error: try to update decimal point separator */ - struct lconv *cv = localeconv(); char old = ls->decpoint; - ls->decpoint = (cv ? cv->decimal_point[0] : '.'); - buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { + ls->decpoint = getlocaledecpoint(); + buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ + if (!buff2d(ls->buff, &seminfo->r)) { /* format error with correct decimal point: no more options */ buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ - luaX_lexerror(ls, "malformed number", TK_NUMBER); + lexerror(ls, "malformed number", TK_NUMBER); } } /* LUA_NUMBER */ +/* +** this function is quite liberal in what it accepts, as 'luaO_str2d' +** will reject ill-formed numerals. +*/ static void read_numeral (LexState *ls, SemInfo *seminfo) { - lua_assert(isdigit(ls->current)); - do { - save_and_next(ls); - } while (isdigit(ls->current) || ls->current == '.'); - if (check_next(ls, "Ee")) /* `E'? */ - check_next(ls, "+-"); /* optional exponent sign */ - while (isalnum(ls->current) || ls->current == '_') - save_and_next(ls); + const char *expo = "Ee"; + int first = ls->current; + lua_assert(lisdigit(ls->current)); + save_and_next(ls); + if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ + expo = "Pp"; + for (;;) { + if (check_next(ls, expo)) /* exponent part? */ + check_next(ls, "+-"); /* optional exponent sign */ + if (lisxdigit(ls->current) || ls->current == '.') + save_and_next(ls); + else break; + } save(ls, '\0'); buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ - if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ + if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ trydecpoint(ls, seminfo); /* try to update decimal point separator */ } +/* +** skip a sequence '[=*[' or ']=*]' and return its number of '='s or +** -1 if sequence is malformed +*/ static int skip_sep (LexState *ls) { int count = 0; int s = ls->current; @@ -219,43 +265,23 @@ static int skip_sep (LexState *ls) { static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { - int cont = 0; - (void)(cont); /* avoid warnings when `cont' is not used */ save_and_next(ls); /* skip 2nd `[' */ if (currIsNewline(ls)) /* string starts with a newline? */ inclinenumber(ls); /* skip it */ for (;;) { switch (ls->current) { case EOZ: - luaX_lexerror(ls, (seminfo) ? "unfinished long string" : - "unfinished long comment", TK_EOS); + lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); break; /* to avoid warnings */ -#if defined(LUA_COMPAT_LSTR) - case '[': { - if (skip_sep(ls) == sep) { - save_and_next(ls); /* skip 2nd `[' */ - cont++; -#if LUA_COMPAT_LSTR == 1 - if (sep == 0) - luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); -#endif - } - break; - } -#endif case ']': { if (skip_sep(ls) == sep) { save_and_next(ls); /* skip 2nd `]' */ -#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 - cont--; - if (sep == 0 && cont >= 0) break; -#endif goto endloop; } break; } - case '\n': - case '\r': { + case '\n': case '\r': { save(ls, '\n'); inclinenumber(ls); if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ @@ -273,51 +299,91 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { } +static void escerror (LexState *ls, int *c, int n, const char *msg) { + int i; + luaZ_resetbuffer(ls->buff); /* prepare error message */ + save(ls, '\\'); + for (i = 0; i < n && c[i] != EOZ; i++) + save(ls, c[i]); + lexerror(ls, msg, TK_STRING); +} + + +static int readhexaesc (LexState *ls) { + int c[3], i; /* keep input for error message */ + int r = 0; /* result accumulator */ + c[0] = 'x'; /* for error message */ + for (i = 1; i < 3; i++) { /* read two hexadecimal digits */ + c[i] = next(ls); + if (!lisxdigit(c[i])) + escerror(ls, c, i + 1, "hexadecimal digit expected"); + r = (r << 4) + luaO_hexavalue(c[i]); + } + return r; +} + + +static int readdecesc (LexState *ls) { + int c[3], i; + int r = 0; /* result accumulator */ + for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ + c[i] = ls->current; + r = 10*r + c[i] - '0'; + next(ls); + } + if (r > UCHAR_MAX) + escerror(ls, c, i, "decimal escape too large"); + return r; +} + + static void read_string (LexState *ls, int del, SemInfo *seminfo) { - save_and_next(ls); + save_and_next(ls); /* keep delimiter (for error messages) */ while (ls->current != del) { switch (ls->current) { case EOZ: - luaX_lexerror(ls, "unfinished string", TK_EOS); - continue; /* to avoid warnings */ + lexerror(ls, "unfinished string", TK_EOS); + break; /* to avoid warnings */ case '\n': case '\r': - luaX_lexerror(ls, "unfinished string", TK_STRING); - continue; /* to avoid warnings */ - case '\\': { - int c; + lexerror(ls, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': { /* escape sequences */ + int c; /* final character to be saved */ next(ls); /* do not save the `\' */ switch (ls->current) { - case 'a': c = '\a'; break; - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case 'v': c = '\v'; break; - case '\n': /* go through */ - case '\r': save(ls, '\n'); inclinenumber(ls); continue; - case EOZ: continue; /* will raise an error next loop */ - default: { - if (!isdigit(ls->current)) - save_and_next(ls); /* handles \\, \", \', and \? */ - else { /* \xxx */ - int i = 0; - c = 0; - do { - c = 10*c + (ls->current-'0'); - next(ls); - } while (++i<3 && isdigit(ls->current)); - if (c > UCHAR_MAX) - luaX_lexerror(ls, "escape sequence too large", TK_STRING); - save(ls, c); + case 'a': c = '\a'; goto read_save; + case 'b': c = '\b'; goto read_save; + case 'f': c = '\f'; goto read_save; + case 'n': c = '\n'; goto read_save; + case 'r': c = '\r'; goto read_save; + case 't': c = '\t'; goto read_save; + case 'v': c = '\v'; goto read_save; + case 'x': c = readhexaesc(ls); goto read_save; + case '\n': case '\r': + inclinenumber(ls); c = '\n'; goto only_save; + case '\\': case '\"': case '\'': + c = ls->current; goto read_save; + case EOZ: goto no_save; /* will raise an error next loop */ + case 'z': { /* zap following span of spaces */ + next(ls); /* skip the 'z' */ + while (lisspace(ls->current)) { + if (currIsNewline(ls)) inclinenumber(ls); + else next(ls); } - continue; + goto no_save; + } + default: { + if (!lisdigit(ls->current)) + escerror(ls, &ls->current, 1, "invalid escape sequence"); + /* digital escape \ddd */ + c = readdecesc(ls); + goto only_save; } } - save(ls, c); - next(ls); - continue; + read_save: next(ls); /* read next character */ + only_save: save(ls, c); /* save 'c' */ + no_save: break; } default: save_and_next(ls); @@ -333,38 +399,41 @@ static int llex (LexState *ls, SemInfo *seminfo) { luaZ_resetbuffer(ls->buff); for (;;) { switch (ls->current) { - case '\n': - case '\r': { + case '\n': case '\r': { /* line breaks */ inclinenumber(ls); - continue; + break; } - case '-': { + case ' ': case '\f': case '\t': case '\v': { /* spaces */ + next(ls); + break; + } + case '-': { /* '-' or '--' (comment) */ next(ls); if (ls->current != '-') return '-'; /* else is a comment */ next(ls); - if (ls->current == '[') { + if (ls->current == '[') { /* long comment? */ int sep = skip_sep(ls); luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ if (sep >= 0) { - read_long_string(ls, NULL, sep); /* long comment */ - luaZ_resetbuffer(ls->buff); - continue; + read_long_string(ls, NULL, sep); /* skip long comment */ + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ + break; } } /* else short comment */ while (!currIsNewline(ls) && ls->current != EOZ) - next(ls); - continue; + next(ls); /* skip until end of line (or end of file) */ + break; } - case '[': { + case '[': { /* long string or simply '[' */ int sep = skip_sep(ls); if (sep >= 0) { read_long_string(ls, seminfo, sep); return TK_STRING; } else if (sep == -1) return '['; - else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); + else lexerror(ls, "invalid long string delimiter", TK_STRING); } case '=': { next(ls); @@ -386,56 +455,52 @@ static int llex (LexState *ls, SemInfo *seminfo) { if (ls->current != '=') return '~'; else { next(ls); return TK_NE; } } - case '"': - case '\'': { + case ':': { + next(ls); + if (ls->current != ':') return ':'; + else { next(ls); return TK_DBCOLON; } + } + case '"': case '\'': { /* short literal strings */ read_string(ls, ls->current, seminfo); return TK_STRING; } - case '.': { + case '.': { /* '.', '..', '...', or number */ save_and_next(ls); if (check_next(ls, ".")) { if (check_next(ls, ".")) - return TK_DOTS; /* ... */ - else return TK_CONCAT; /* .. */ - } - else if (!isdigit(ls->current)) return '.'; - else { - read_numeral(ls, seminfo); - return TK_NUMBER; + return TK_DOTS; /* '...' */ + else return TK_CONCAT; /* '..' */ } + else if (!lisdigit(ls->current)) return '.'; + /* else go through */ + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + read_numeral(ls, seminfo); + return TK_NUMBER; } case EOZ: { return TK_EOS; } default: { - if (isspace(ls->current)) { - lua_assert(!currIsNewline(ls)); - next(ls); - continue; - } - else if (isdigit(ls->current)) { - read_numeral(ls, seminfo); - return TK_NUMBER; - } - else if (isalpha(ls->current) || ls->current == '_') { - /* identifier or reserved word */ + if (lislalpha(ls->current)) { /* identifier or reserved word? */ TString *ts; do { save_and_next(ls); - } while (isalnum(ls->current) || ls->current == '_'); + } while (lislalnum(ls->current)); ts = luaX_newstring(ls, luaZ_buffer(ls->buff), luaZ_bufflen(ls->buff)); - if (ts->tsv.reserved > 0) /* reserved word? */ - return ts->tsv.reserved - 1 + FIRST_RESERVED; + seminfo->ts = ts; + if (isreserved(ts)) /* reserved word? */ + return ts->tsv.extra - 1 + FIRST_RESERVED; else { - seminfo->ts = ts; return TK_NAME; } } - else { + else { /* single-char tokens (+ - / ...) */ int c = ls->current; next(ls); - return c; /* single-char tokens (+ - / ...) */ + return c; } } } @@ -454,8 +519,9 @@ void luaX_next (LexState *ls) { } -void luaX_lookahead (LexState *ls) { +int luaX_lookahead (LexState *ls) { lua_assert(ls->lookahead.token == TK_EOS); ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); + return ls->lookahead.token; } diff --git a/src/mod/languages/mod_lua/lua/llex.h b/src/mod/languages/mod_lua/lua/llex.h index a9201cee48..9ca8a29948 100644 --- a/src/mod/languages/mod_lua/lua/llex.h +++ b/src/mod/languages/mod_lua/lua/llex.h @@ -1,5 +1,5 @@ /* -** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: llex.h,v 1.72 2011/11/30 12:43:51 roberto Exp $ ** Lexical Analyzer ** See Copyright Notice in lua.h */ @@ -13,8 +13,6 @@ #define FIRST_RESERVED 257 -/* maximum length of a reserved word */ -#define TOKEN_LEN (sizeof("function")/sizeof(char)) /* @@ -25,21 +23,17 @@ enum RESERVED { /* terminal symbols denoted by reserved words */ TK_AND = FIRST_RESERVED, TK_BREAK, TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, - TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, /* other terminal symbols */ - TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, - TK_NAME, TK_STRING, TK_EOS + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, + TK_NUMBER, TK_NAME, TK_STRING }; /* number of reserved words */ #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) -/* array with token `names' */ -LUAI_DATA const char *const luaX_tokens []; - - typedef union { lua_Number r; TString *ts; @@ -52,29 +46,32 @@ typedef struct Token { } Token; +/* state of the lexer plus state of the parser when shared by all + functions */ typedef struct LexState { int current; /* current character (charint) */ int linenumber; /* input line counter */ int lastline; /* line of last token `consumed' */ Token t; /* current token */ Token lookahead; /* look ahead token */ - struct FuncState *fs; /* `FuncState' is private to the parser */ + struct FuncState *fs; /* current function (parser) */ struct lua_State *L; ZIO *z; /* input stream */ Mbuffer *buff; /* buffer for tokens */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ TString *source; /* current source name */ + TString *envn; /* environment variable name */ char decpoint; /* locale decimal point */ } LexState; LUAI_FUNC void luaX_init (lua_State *L); LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, - TString *source); + TString *source, int firstchar); LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); LUAI_FUNC void luaX_next (LexState *ls); -LUAI_FUNC void luaX_lookahead (LexState *ls); -LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); -LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC int luaX_lookahead (LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); diff --git a/src/mod/languages/mod_lua/lua/llimits.h b/src/mod/languages/mod_lua/lua/llimits.h index ca8dcb7224..1b8c79bda2 100644 --- a/src/mod/languages/mod_lua/lua/llimits.h +++ b/src/mod/languages/mod_lua/lua/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: llimits.h,v 1.103 2013/02/20 14:08:56 roberto Exp $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -15,7 +15,7 @@ #include "lua.h" -typedef LUAI_UINT32 lu_int32; +typedef unsigned LUA_INT32 lu_int32; typedef LUAI_UMEM lu_mem; @@ -31,6 +31,8 @@ typedef unsigned char lu_byte; #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) +#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2)) + #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ @@ -44,6 +46,10 @@ typedef unsigned char lu_byte; /* type to ensure maximum alignment */ +#if !defined(LUAI_USER_ALIGNMENT_T) +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } +#endif + typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; @@ -52,34 +58,73 @@ typedef LUAI_UACNUMBER l_uacNumber; /* internal assertions for in-house debugging */ -#ifdef lua_assert - +#if defined(lua_assert) #define check_exp(c,e) (lua_assert(c), (e)) -#define api_check(l,e) lua_assert(e) - +/* to avoid problems with conditions too long */ +#define lua_longassert(c) { if (!(c)) lua_assert(0); } #else - #define lua_assert(c) ((void)0) #define check_exp(c,e) (e) -#define api_check luai_apicheck +#define lua_longassert(c) ((void)0) +#endif + +/* +** assertion for checking API calls +*/ +#if !defined(luai_apicheck) + +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,e) assert(e) +#else +#define luai_apicheck(L,e) lua_assert(e) +#endif #endif +#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) -#ifndef UNUSED + +#if !defined(UNUSED) #define UNUSED(x) ((void)(x)) /* to avoid warnings */ #endif -#ifndef cast #define cast(t, exp) ((t)(exp)) -#endif #define cast_byte(i) cast(lu_byte, (i)) #define cast_num(i) cast(lua_Number, (i)) #define cast_int(i) cast(int, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) +/* +** non-return type +*/ +#if defined(__GNUC__) +#define l_noret void __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define l_noret void __declspec(noreturn) +#else +#define l_noret void +#endif + + + +/* +** maximum depth for nested C calls and syntactical nested non-terminals +** in a program. (Value must fit in an unsigned short int.) +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 200 +#endif + +/* +** maximum number of upvalues in a closure (both C and Lua). (Value +** must fit in an unsigned char.) +*/ +#define MAXUPVAL UCHAR_MAX + /* ** type for virtual-machine instructions @@ -95,34 +140,170 @@ typedef lu_int32 Instruction; /* minimum size for the string table (must be power of 2) */ -#ifndef MINSTRTABSIZE +#if !defined(MINSTRTABSIZE) #define MINSTRTABSIZE 32 #endif /* minimum size for string buffer */ -#ifndef LUA_MINBUFFER +#if !defined(LUA_MINBUFFER) #define LUA_MINBUFFER 32 #endif -#ifndef lua_lock -#define lua_lock(L) ((void) 0) +#if !defined(lua_lock) +#define lua_lock(L) ((void) 0) #define lua_unlock(L) ((void) 0) #endif -#ifndef luai_threadyield +#if !defined(luai_threadyield) #define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} #endif /* -** macro to control inclusion of some hard tests on stack reallocation -*/ -#ifndef HARDSTACKTESTS -#define condhardstacktests(x) ((void)0) +** these macros allow user-specific actions on threads when you defined +** LUAI_EXTRASPACE and need to do something extra when a thread is +** created/deleted/resumed/yielded. +*/ +#if !defined(luai_userstateopen) +#define luai_userstateopen(L) ((void)L) +#endif + +#if !defined(luai_userstateclose) +#define luai_userstateclose(L) ((void)L) +#endif + +#if !defined(luai_userstatethread) +#define luai_userstatethread(L,L1) ((void)L) +#endif + +#if !defined(luai_userstatefree) +#define luai_userstatefree(L,L1) ((void)L) +#endif + +#if !defined(luai_userstateresume) +#define luai_userstateresume(L,n) ((void)L) +#endif + +#if !defined(luai_userstateyield) +#define luai_userstateyield(L,n) ((void)L) +#endif + +/* +** lua_number2int is a macro to convert lua_Number to int. +** lua_number2integer is a macro to convert lua_Number to lua_Integer. +** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. +** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. +** luai_hashnum is a macro to hash a lua_Number value into an integer. +** The hash must be deterministic and give reasonable values for +** both small and large values (outside the range of integers). +*/ + +#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ +/* trick with Microsoft assembler for X86 */ + +#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} +#define lua_number2integer(i,n) lua_number2int(i, n) +#define lua_number2unsigned(i,n) \ + {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} + + +#elif defined(LUA_IEEE754TRICK) /* }{ */ +/* the next trick should work on any machine using IEEE754 with + a 32-bit int type */ + +union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; + +#if !defined(LUA_IEEEENDIAN) /* { */ +#define LUAI_EXTRAIEEE \ + static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; +#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) #else -#define condhardstacktests(x) x +#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN +#define LUAI_EXTRAIEEE /* empty */ +#endif /* } */ + +#define lua_number2int32(i,n,t) \ + { LUAI_EXTRAIEEE \ + volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ + (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } + +#define luai_hashnum(i,n) \ + { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ + (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ + +#define lua_number2int(i,n) lua_number2int32(i, n, int) +#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) + +/* the trick can be expanded to lua_Integer when it is a 32-bit value */ +#if defined(LUA_IEEELL) +#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) +#endif + +#endif /* } */ + + +/* the following definitions always work, but may be slow */ + +#if !defined(lua_number2int) +#define lua_number2int(i,n) ((i)=(int)(n)) +#endif + +#if !defined(lua_number2integer) +#define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) +#endif + +#if !defined(lua_number2unsigned) /* { */ +/* the following definition assures proper modulo behavior */ +#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) +#include +#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) +#define lua_number2unsigned(i,n) \ + ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) +#else +#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) +#endif +#endif /* } */ + + +#if !defined(lua_unsigned2number) +/* on several machines, coercion from unsigned to double is slow, + so it may be worth to avoid */ +#define lua_unsigned2number(u) \ + (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) +#endif + + + +#if defined(ltable_c) && !defined(luai_hashnum) + +#include +#include + +#define luai_hashnum(i,n) { int e; \ + n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ + lua_number2int(i, n); i += e; } + +#endif + + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if !defined(HARDSTACKTESTS) +#define condmovestack(L) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) +#endif + +#if !defined(HARDMEMTESTS) +#define condchangemem(L) condmovestack(L) +#else +#define condchangemem(L) \ + ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) #endif #endif diff --git a/src/mod/languages/mod_lua/lua/lmathlib.c b/src/mod/languages/mod_lua/lua/lmathlib.c index 441fbf736c..a49f1fd25a 100644 --- a/src/mod/languages/mod_lua/lua/lmathlib.c +++ b/src/mod/languages/mod_lua/lua/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lmathlib.c,v 1.83 2013/03/07 18:21:32 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -18,111 +18,126 @@ #undef PI -#define PI (3.14159265358979323846) -#define RADIANS_PER_DEGREE (PI/180.0) +#define PI ((lua_Number)(3.1415926535897932384626433832795)) +#define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0)) static int math_abs (lua_State *L) { - lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); return 1; } static int math_sin (lua_State *L) { - lua_pushnumber(L, sin(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); return 1; } static int math_sinh (lua_State *L) { - lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); return 1; } static int math_cos (lua_State *L) { - lua_pushnumber(L, cos(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); return 1; } static int math_cosh (lua_State *L) { - lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); return 1; } static int math_tan (lua_State *L) { - lua_pushnumber(L, tan(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); return 1; } static int math_tanh (lua_State *L) { - lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); return 1; } static int math_asin (lua_State *L) { - lua_pushnumber(L, asin(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); return 1; } static int math_acos (lua_State *L) { - lua_pushnumber(L, acos(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); return 1; } static int math_atan (lua_State *L) { - lua_pushnumber(L, atan(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1))); return 1; } static int math_atan2 (lua_State *L) { - lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); return 1; } static int math_ceil (lua_State *L) { - lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1))); return 1; } static int math_floor (lua_State *L) { - lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1))); return 1; } static int math_fmod (lua_State *L) { - lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); return 1; } static int math_modf (lua_State *L) { - double ip; - double fp = modf(luaL_checknumber(L, 1), &ip); + lua_Number ip; + lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip); lua_pushnumber(L, ip); lua_pushnumber(L, fp); return 2; } static int math_sqrt (lua_State *L) { - lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); return 1; } static int math_pow (lua_State *L) { - lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + lua_Number x = luaL_checknumber(L, 1); + lua_Number y = luaL_checknumber(L, 2); + lua_pushnumber(L, l_mathop(pow)(x, y)); return 1; } static int math_log (lua_State *L) { - lua_pushnumber(L, log(luaL_checknumber(L, 1))); + lua_Number x = luaL_checknumber(L, 1); + lua_Number res; + if (lua_isnoneornil(L, 2)) + res = l_mathop(log)(x); + else { + lua_Number base = luaL_checknumber(L, 2); + if (base == (lua_Number)10.0) res = l_mathop(log10)(x); + else res = l_mathop(log)(x)/l_mathop(log)(base); + } + lua_pushnumber(L, res); return 1; } +#if defined(LUA_COMPAT_LOG10) static int math_log10 (lua_State *L) { - lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); return 1; } +#endif static int math_exp (lua_State *L) { - lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); return 1; } @@ -138,13 +153,15 @@ static int math_rad (lua_State *L) { static int math_frexp (lua_State *L) { int e; - lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); lua_pushinteger(L, e); return 2; } static int math_ldexp (lua_State *L) { - lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); + lua_Number x = luaL_checknumber(L, 1); + int ep = luaL_checkint(L, 2); + lua_pushnumber(L, l_mathop(ldexp)(x, ep)); return 1; } @@ -188,16 +205,16 @@ static int math_random (lua_State *L) { break; } case 1: { /* only upper limit */ - int u = luaL_checkint(L, 1); - luaL_argcheck(L, 1<=u, 1, "interval is empty"); - lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ + lua_Number u = luaL_checknumber(L, 1); + luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); + lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */ break; } case 2: { /* lower and upper limits */ - int l = luaL_checkint(L, 1); - int u = luaL_checkint(L, 2); - luaL_argcheck(L, l<=u, 2, "interval is empty"); - lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ + lua_Number l = luaL_checknumber(L, 1); + lua_Number u = luaL_checknumber(L, 2); + luaL_argcheck(L, l <= u, 2, "interval is empty"); + lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */ break; } default: return luaL_error(L, "wrong number of arguments"); @@ -207,7 +224,8 @@ static int math_random (lua_State *L) { static int math_randomseed (lua_State *L) { - srand(luaL_checkint(L, 1)); + srand(luaL_checkunsigned(L, 1)); + (void)rand(); /* discard first value to avoid undesirable correlations */ return 0; } @@ -227,7 +245,9 @@ static const luaL_Reg mathlib[] = { {"fmod", math_fmod}, {"frexp", math_frexp}, {"ldexp", math_ldexp}, +#if defined(LUA_COMPAT_LOG10) {"log10", math_log10}, +#endif {"log", math_log}, {"max", math_max}, {"min", math_min}, @@ -248,16 +268,12 @@ static const luaL_Reg mathlib[] = { /* ** Open math library */ -LUALIB_API int luaopen_math (lua_State *L) { - luaL_register(L, LUA_MATHLIBNAME, mathlib); +LUAMOD_API int luaopen_math (lua_State *L) { + luaL_newlib(L, mathlib); lua_pushnumber(L, PI); lua_setfield(L, -2, "pi"); lua_pushnumber(L, HUGE_VAL); lua_setfield(L, -2, "huge"); -#if defined(LUA_COMPAT_MOD) - lua_getfield(L, -1, "fmod"); - lua_setfield(L, -2, "mod"); -#endif return 1; } diff --git a/src/mod/languages/mod_lua/lua/lmem.c b/src/mod/languages/mod_lua/lua/lmem.c index ae7d8c965f..3f88496e09 100644 --- a/src/mod/languages/mod_lua/lua/lmem.c +++ b/src/mod/languages/mod_lua/lua/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lmem.c,v 1.84 2012/05/23 15:41:53 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -14,6 +14,7 @@ #include "ldebug.h" #include "ldo.h" +#include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" @@ -25,12 +26,11 @@ ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); ** (`osize' is the old size, `nsize' is the new size) ** -** Lua ensures that (ptr == NULL) iff (osize == 0). -** -** * frealloc(ud, NULL, 0, x) creates a new block of size `x' +** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no +** matter 'x'). ** ** * frealloc(ud, p, x, 0) frees the block `p' -** (in this specific case, frealloc must return NULL). +** (in this specific case, frealloc must return NULL); ** particularly, frealloc(ud, NULL, 0, 0) does nothing ** (which is equivalent to free(NULL) in ANSI C) ** @@ -44,12 +44,12 @@ void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, - int limit, const char *errormsg) { + int limit, const char *what) { void *newblock; int newsize; if (*size >= limit/2) { /* cannot double it? */ if (*size >= limit) /* cannot grow even a little? */ - luaG_runerror(L, errormsg); + luaG_runerror(L, "too many %s (limit is %d)", what, limit); newsize = limit; /* still have at least one free place */ } else { @@ -63,9 +63,8 @@ void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, } -void *luaM_toobig (lua_State *L) { +l_noret luaM_toobig (lua_State *L) { luaG_runerror(L, "memory allocation error: block too big"); - return NULL; /* to avoid warnings */ } @@ -74,13 +73,27 @@ void *luaM_toobig (lua_State *L) { ** generic allocation routine. */ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + void *newblock; global_State *g = G(L); - lua_assert((osize == 0) == (block == NULL)); - block = (*g->frealloc)(g->ud, block, osize, nsize); - if (block == NULL && nsize > 0) - luaD_throw(L, LUA_ERRMEM); - lua_assert((nsize == 0) == (block == NULL)); - g->totalbytes = (g->totalbytes - osize) + nsize; - return block; + size_t realosize = (block) ? osize : 0; + lua_assert((realosize == 0) == (block == NULL)); +#if defined(HARDMEMTESTS) + if (nsize > realosize && g->gcrunning) + luaC_fullgc(L, 1); /* force a GC whenever possible */ +#endif + newblock = (*g->frealloc)(g->ud, block, osize, nsize); + if (newblock == NULL && nsize > 0) { + api_check(L, nsize > realosize, + "realloc cannot fail when shrinking a block"); + if (g->gcrunning) { + luaC_fullgc(L, 1); /* try to free some memory... */ + newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ + } + if (newblock == NULL) + luaD_throw(L, LUA_ERRMEM); + } + lua_assert((nsize == 0) == (newblock == NULL)); + g->GCdebt = (g->GCdebt + nsize) - realosize; + return newblock; } diff --git a/src/mod/languages/mod_lua/lua/lmem.h b/src/mod/languages/mod_lua/lua/lmem.h index 7c2dcb3220..5f850999a9 100644 --- a/src/mod/languages/mod_lua/lua/lmem.h +++ b/src/mod/languages/mod_lua/lua/lmem.h @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lmem.h,v 1.40 2013/02/20 14:08:21 roberto Exp $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -13,23 +13,30 @@ #include "llimits.h" #include "lua.h" -#define MEMERRMSG "not enough memory" - +/* +** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is +** always constant. +** The macro is somewhat complex to avoid warnings: +** +1 avoids warnings of "comparison has constant result"; +** cast to 'void' avoids warnings of "value unused". +*/ #define luaM_reallocv(L,b,on,n,e) \ - ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ - luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ - luaM_toobig(L)) + (cast(void, \ + (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e))) #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) -#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) +#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) -#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) #define luaM_newvector(L,n,t) \ cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) +#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) + #define luaM_growvector(L,v,nelems,size,t,limit,e) \ if ((nelems)+1 > (size)) \ ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) @@ -37,13 +44,14 @@ #define luaM_reallocvector(L, v,oldn,n,t) \ ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) +LUAI_FUNC l_noret luaM_toobig (lua_State *L); +/* not to be called directly */ LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, size_t size); -LUAI_FUNC void *luaM_toobig (lua_State *L); LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elem, int limit, - const char *errormsg); + const char *what); #endif diff --git a/src/mod/languages/mod_lua/lua/loadlib.c b/src/mod/languages/mod_lua/lua/loadlib.c index 0589b61fed..a9959277bd 100644 --- a/src/mod/languages/mod_lua/lua/loadlib.c +++ b/src/mod/languages/mod_lua/lua/loadlib.c @@ -1,14 +1,22 @@ /* -** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ +** $Id: loadlib.c,v 1.111 2012/05/30 12:33:44 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** ** This module contains an implementation of loadlib for Unix systems -** that have dlfcn, an implementation for Darwin (Mac OS X), an -** implementation for Windows, and a stub for other systems. +** that have dlfcn, an implementation for Windows, and a stub for other +** systems. */ +/* +** if needed, includes windows header before everything else +*/ +#if defined(_WIN32) +#include +#endif + + #include #include @@ -22,6 +30,61 @@ #include "lualib.h" +/* +** LUA_PATH and LUA_CPATH are the names of the environment +** variables that Lua check to set its paths. +*/ +#if !defined(LUA_PATH) +#define LUA_PATH "LUA_PATH" +#endif + +#if !defined(LUA_CPATH) +#define LUA_CPATH "LUA_CPATH" +#endif + +#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + +#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX +#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +** LUA_IGMARK is a mark to ignore all before it when building the +** luaopen_ function name. +*/ +#if !defined (LUA_PATH_SEP) +#define LUA_PATH_SEP ";" +#endif +#if !defined (LUA_PATH_MARK) +#define LUA_PATH_MARK "?" +#endif +#if !defined (LUA_EXEC_DIR) +#define LUA_EXEC_DIR "!" +#endif +#if !defined (LUA_IGMARK) +#define LUA_IGMARK "-" +#endif + + +/* +** LUA_CSUBSEP is the character that replaces dots in submodule names +** when searching for a C loader. +** LUA_LSUBSEP is the character that replaces dots in submodule names +** when searching for a Lua loader. +*/ +#if !defined(LUA_CSUBSEP) +#define LUA_CSUBSEP LUA_DIRSEP +#endif + +#if !defined(LUA_LSUBSEP) +#define LUA_LSUBSEP LUA_DIRSEP +#endif + + /* prefix for open functions in C libraries */ #define LUA_POF "luaopen_" @@ -29,9 +92,9 @@ #define LUA_OFSEP "_" -#define LIBPREFIX "LOADLIB: " +/* table (in the registry) that keeps handles for all loaded C libraries */ +#define CLIBS "_CLIBS" -#define POF LUA_POF #define LIB_FAIL "open" @@ -42,13 +105,16 @@ #define setprogdir(L) ((void)0) +/* +** system-dependent functions +*/ static void ll_unloadlib (void *lib); -static void *ll_load (lua_State *L, const char *path); +static void *ll_load (lua_State *L, const char *path, int seeglb); static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); -#if defined(LUA_DL_DLOPEN) +#if defined(LUA_USE_DLOPEN) /* ** {======================================================================== ** This is an implementation of loadlib based on the dlfcn interface. @@ -65,8 +131,8 @@ static void ll_unloadlib (void *lib) { } -static void *ll_load (lua_State *L, const char *path) { - void *lib = dlopen(path, RTLD_NOW); +static void *ll_load (lua_State *L, const char *path, int seeglb) { + void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); if (lib == NULL) lua_pushstring(L, dlerror()); return lib; } @@ -89,11 +155,16 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { ** ======================================================================= */ -#include - - #undef setprogdir +/* +** optional flags for LoadLibraryEx +*/ +#if !defined(LUA_LLE_FLAGS) +#define LUA_LLE_FLAGS 0 +#endif + + static void setprogdir (lua_State *L) { char buff[MAX_PATH + 1]; char *lb; @@ -103,7 +174,7 @@ static void setprogdir (lua_State *L) { luaL_error(L, "unable to get ModuleFileName"); else { *lb = '\0'; - luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); lua_remove(L, -2); /* remove original string */ } } @@ -113,26 +184,27 @@ static void pusherror (lua_State *L) { int error = GetLastError(); char buffer[128]; if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error, 0, buffer, sizeof(buffer), NULL)) + NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) lua_pushstring(L, buffer); else lua_pushfstring(L, "system error %d\n", error); } static void ll_unloadlib (void *lib) { - FreeLibrary((HINSTANCE)lib); + FreeLibrary((HMODULE)lib); } -static void *ll_load (lua_State *L, const char *path) { - HINSTANCE lib = LoadLibraryA(path); +static void *ll_load (lua_State *L, const char *path, int seeglb) { + HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); + (void)(seeglb); /* not used: symbols are 'global' by default */ if (lib == NULL) pusherror(L); return lib; } static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); + lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); if (f == NULL) pusherror(L); return f; } @@ -140,88 +212,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { /* }====================================================== */ - -#elif defined(LUA_DL_DYLD) -/* -** {====================================================================== -** Native Mac OS X / Darwin Implementation -** ======================================================================= -*/ - -#include - - -/* Mac appends a `_' before C function names */ -#undef POF -#define POF "_" LUA_POF - - -static void pusherror (lua_State *L) { - const char *err_str; - const char *err_file; - NSLinkEditErrors err; - int err_num; - NSLinkEditError(&err, &err_num, &err_file, &err_str); - lua_pushstring(L, err_str); -} - - -static const char *errorfromcode (NSObjectFileImageReturnCode ret) { - switch (ret) { - case NSObjectFileImageInappropriateFile: - return "file is not a bundle"; - case NSObjectFileImageArch: - return "library is for wrong CPU type"; - case NSObjectFileImageFormat: - return "bad format"; - case NSObjectFileImageAccess: - return "cannot access file"; - case NSObjectFileImageFailure: - default: - return "unable to load library"; - } -} - - -static void ll_unloadlib (void *lib) { - NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); -} - - -static void *ll_load (lua_State *L, const char *path) { - NSObjectFileImage img; - NSObjectFileImageReturnCode ret; - /* this would be a rare case, but prevents crashing if it happens */ - if (!_dyld_present()) { - lua_pushliteral(L, "dyld not present"); - return NULL; - } - ret = NSCreateObjectFileImageFromFile(path, &img); - if (ret == NSObjectFileImageSuccess) { - NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | - NSLINKMODULE_OPTION_RETURN_ON_ERROR); - NSDestroyObjectFileImage(img); - if (mod == NULL) pusherror(L); - return mod; - } - lua_pushstring(L, errorfromcode(ret)); - return NULL; -} - - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); - if (nss == NULL) { - lua_pushfstring(L, "symbol " LUA_QS " not found", sym); - return NULL; - } - return (lua_CFunction)NSAddressOfSymbol(nss); -} - -/* }====================================================== */ - - - #else /* ** {====================================================== @@ -237,19 +227,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { static void ll_unloadlib (void *lib) { - (void)lib; /* to avoid warnings */ + (void)(lib); /* not used */ } -static void *ll_load (lua_State *L, const char *path) { - (void)path; /* to avoid warnings */ +static void *ll_load (lua_State *L, const char *path, int seeglb) { + (void)(path); (void)(seeglb); /* not used */ lua_pushliteral(L, DLMSG); return NULL; } static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - (void)lib; (void)sym; /* to avoid warnings */ + (void)(lib); (void)(sym); /* not used */ lua_pushliteral(L, DLMSG); return NULL; } @@ -258,50 +248,58 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { #endif - -static void **ll_register (lua_State *L, const char *path) { - void **plib; - lua_pushfstring(L, "%s%s", LIBPREFIX, path); - lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ - if (!lua_isnil(L, -1)) /* is there an entry? */ - plib = (void **)lua_touserdata(L, -1); - else { /* no entry yet; create one */ - lua_pop(L, 1); - plib = (void **)lua_newuserdata(L, sizeof(const void *)); - *plib = NULL; - luaL_getmetatable(L, "_LOADLIB"); - lua_setmetatable(L, -2); - lua_pushfstring(L, "%s%s", LIBPREFIX, path); - lua_pushvalue(L, -2); - lua_settable(L, LUA_REGISTRYINDEX); - } +static void *ll_checkclib (lua_State *L, const char *path) { + void *plib; + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_getfield(L, -1, path); + plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ return plib; } +static void ll_addtoclib (lua_State *L, const char *path, void *plib) { + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ +} + + /* -** __gc tag method: calls library's `ll_unloadlib' function with the lib -** handle +** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib +** handles in list CLIBS */ static int gctm (lua_State *L) { - void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); - if (*lib) ll_unloadlib(*lib); - *lib = NULL; /* mark library as closed */ + int n = luaL_len(L, 1); + for (; n >= 1; n--) { /* for each handle, in reverse order */ + lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ + ll_unloadlib(lua_touserdata(L, -1)); + lua_pop(L, 1); /* pop handle */ + } return 0; } static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { - void **reg = ll_register(L, path); - if (*reg == NULL) *reg = ll_load(L, path); - if (*reg == NULL) - return ERRLIB; /* unable to load library */ + void *reg = ll_checkclib(L, path); /* check loaded C libraries */ + if (reg == NULL) { /* must load library? */ + reg = ll_load(L, path, *sym == '*'); + if (reg == NULL) return ERRLIB; /* unable to load library */ + ll_addtoclib(L, path, reg); + } + if (*sym == '*') { /* loading only library (no function)? */ + lua_pushboolean(L, 1); /* return 'true' */ + return 0; /* no errors */ + } else { - lua_CFunction f = ll_sym(L, *reg, sym); + lua_CFunction f = ll_sym(L, reg, sym); if (f == NULL) return ERRFUNC; /* unable to find function */ - lua_pushcfunction(L, f); - return 0; /* return function */ + lua_pushcfunction(L, f); /* else create new function */ + return 0; /* no errors */ } } @@ -339,104 +337,137 @@ static int readable (const char *filename) { static const char *pushnexttemplate (lua_State *L, const char *path) { const char *l; - while (*path == *LUA_PATHSEP) path++; /* skip separators */ + while (*path == *LUA_PATH_SEP) path++; /* skip separators */ if (*path == '\0') return NULL; /* no more templates */ - l = strchr(path, *LUA_PATHSEP); /* find next separator */ + l = strchr(path, *LUA_PATH_SEP); /* find next separator */ if (l == NULL) l = path + strlen(path); lua_pushlstring(L, path, l - path); /* template */ return l; } -static const char *findfile (lua_State *L, const char *name, - const char *pname) { - const char *path; - name = luaL_gsub(L, name, ".", LUA_DIRSEP); - lua_getfield(L, LUA_ENVIRONINDEX, pname); - path = lua_tostring(L, -1); - if (path == NULL) - luaL_error(L, LUA_QL("package.%s") " must be a string", pname); - lua_pushliteral(L, ""); /* error accumulator */ +static const char *searchpath (lua_State *L, const char *name, + const char *path, + const char *sep, + const char *dirsep) { + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + if (*sep != '\0') /* non-empty separator? */ + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ while ((path = pushnexttemplate(L, path)) != NULL) { - const char *filename; - filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); + const char *filename = luaL_gsub(L, lua_tostring(L, -1), + LUA_PATH_MARK, name); lua_remove(L, -2); /* remove path template */ if (readable(filename)) /* does file exist and is readable? */ return filename; /* return that file name */ lua_pushfstring(L, "\n\tno file " LUA_QS, filename); lua_remove(L, -2); /* remove file name */ - lua_concat(L, 2); /* add entry to possible error message */ + luaL_addvalue(&msg); /* concatenate error msg. entry */ } + luaL_pushresult(&msg); /* create error message */ return NULL; /* not found */ } -static void loaderror (lua_State *L, const char *filename) { - luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", - lua_tostring(L, 1), filename, lua_tostring(L, -1)); +static int ll_searchpath (lua_State *L) { + const char *f = searchpath(L, luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, "."), + luaL_optstring(L, 4, LUA_DIRSEP)); + if (f != NULL) return 1; + else { /* error message is on top of the stack */ + lua_pushnil(L); + lua_insert(L, -2); + return 2; /* return nil + error message */ + } } -static int loader_Lua (lua_State *L) { +static const char *findfile (lua_State *L, const char *name, + const char *pname, + const char *dirsep) { + const char *path; + lua_getfield(L, lua_upvalueindex(1), pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + return searchpath(L, name, path, ".", dirsep); +} + + +static int checkload (lua_State *L, int stat, const char *filename) { + if (stat) { /* module loaded successfully? */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; /* return open function and file name */ + } + else + return luaL_error(L, "error loading module " LUA_QS + " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int searcher_Lua (lua_State *L) { const char *filename; const char *name = luaL_checkstring(L, 1); - filename = findfile(L, name, "path"); - if (filename == NULL) return 1; /* library not found in this path */ - if (luaL_loadfile(L, filename) != 0) - loaderror(L, filename); - return 1; /* library loaded successfully */ + filename = findfile(L, name, "path", LUA_LSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); } -static const char *mkfuncname (lua_State *L, const char *modname) { +static int loadfunc (lua_State *L, const char *filename, const char *modname) { const char *funcname; - const char *mark = strchr(modname, *LUA_IGMARK); - if (mark) modname = mark + 1; - funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); - funcname = lua_pushfstring(L, POF"%s", funcname); - lua_remove(L, -2); /* remove 'gsub' result */ - return funcname; + const char *mark; + modname = luaL_gsub(L, modname, ".", LUA_OFSEP); + mark = strchr(modname, *LUA_IGMARK); + if (mark) { + int stat; + funcname = lua_pushlstring(L, modname, mark - modname); + funcname = lua_pushfstring(L, LUA_POF"%s", funcname); + stat = ll_loadfunc(L, filename, funcname); + if (stat != ERRFUNC) return stat; + modname = mark + 1; /* else go ahead and try old-style name */ + } + funcname = lua_pushfstring(L, LUA_POF"%s", modname); + return ll_loadfunc(L, filename, funcname); } -static int loader_C (lua_State *L) { - const char *funcname; +static int searcher_C (lua_State *L) { const char *name = luaL_checkstring(L, 1); - const char *filename = findfile(L, name, "cpath"); - if (filename == NULL) return 1; /* library not found in this path */ - funcname = mkfuncname(L, name); - if (ll_loadfunc(L, filename, funcname) != 0) - loaderror(L, filename); - return 1; /* library loaded successfully */ + const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (loadfunc(L, filename, name) == 0), filename); } -static int loader_Croot (lua_State *L) { - const char *funcname; +static int searcher_Croot (lua_State *L) { const char *filename; const char *name = luaL_checkstring(L, 1); const char *p = strchr(name, '.'); int stat; if (p == NULL) return 0; /* is root */ lua_pushlstring(L, name, p - name); - filename = findfile(L, lua_tostring(L, -1), "cpath"); + filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); if (filename == NULL) return 1; /* root not found */ - funcname = mkfuncname(L, name); - if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { - if (stat != ERRFUNC) loaderror(L, filename); /* real error */ - lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, - name, filename); - return 1; /* function not found */ + if ((stat = loadfunc(L, filename, name)) != 0) { + if (stat != ERRFUNC) + return checkload(L, 0, filename); /* real error */ + else { /* open function not found */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; + } } - return 1; + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; } -static int loader_preload (lua_State *L) { +static int searcher_preload (lua_State *L) { const char *name = luaL_checkstring(L, 1); - lua_getfield(L, LUA_ENVIRONINDEX, "preload"); - if (!lua_istable(L, -1)) - luaL_error(L, LUA_QL("package.preload") " must be a table"); + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_getfield(L, -1, name); if (lua_isnil(L, -1)) /* not found? */ lua_pushfstring(L, "\n\tno field package.preload['%s']", name); @@ -444,48 +475,53 @@ static int loader_preload (lua_State *L) { } -static const int sentinel_ = 0; -#define sentinel ((void *)&sentinel_) +static void findloader (lua_State *L, const char *name) { + int i; + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ + if (!lua_istable(L, 3)) + luaL_error(L, LUA_QL("package.searchers") " must be a table"); + /* iterate over available searchers to find a loader */ + for (i = 1; ; i++) { + lua_rawgeti(L, 3, i); /* get a searcher */ + if (lua_isnil(L, -1)) { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_pushresult(&msg); /* create error message */ + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -1)); + } + lua_pushstring(L, name); + lua_call(L, 1, 2); /* call it */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ + return; /* module loader found */ + else if (lua_isstring(L, -2)) { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(&msg); /* concatenate error message */ + } + else + lua_pop(L, 2); /* remove both returns */ + } +} static int ll_require (lua_State *L) { const char *name = luaL_checkstring(L, 1); - int i; lua_settop(L, 1); /* _LOADED table will be at index 2 */ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, 2, name); - if (lua_toboolean(L, -1)) { /* is it there? */ - if (lua_touserdata(L, -1) == sentinel) /* check loops */ - luaL_error(L, "loop or previous error loading module " LUA_QS, name); + lua_getfield(L, 2, name); /* _LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ return 1; /* package is already loaded */ - } - /* else must load it; iterate over available loaders */ - lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); - if (!lua_istable(L, -1)) - luaL_error(L, LUA_QL("package.loaders") " must be a table"); - lua_pushliteral(L, ""); /* error message accumulator */ - for (i=1; ; i++) { - lua_rawgeti(L, -2, i); /* get a loader */ - if (lua_isnil(L, -1)) - luaL_error(L, "module " LUA_QS " not found:%s", - name, lua_tostring(L, -2)); - lua_pushstring(L, name); - lua_call(L, 1, 1); /* call it */ - if (lua_isfunction(L, -1)) /* did it find module? */ - break; /* module loaded successfully */ - else if (lua_isstring(L, -1)) /* loader returned error message? */ - lua_concat(L, 2); /* accumulate it */ - else - lua_pop(L, 1); - } - lua_pushlightuserdata(L, sentinel); - lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ - lua_pushstring(L, name); /* pass name as argument to module */ - lua_call(L, 1, 1); /* run loaded module */ + /* else must load package */ + lua_pop(L, 1); /* remove 'getfield' result */ + findloader(L, name); + lua_pushstring(L, name); /* pass name as argument to module loader */ + lua_insert(L, -2); /* name is 1st argument (before search data) */ + lua_call(L, 2, 1); /* run loader to load module */ if (!lua_isnil(L, -1)) /* non-nil return? */ lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ lua_getfield(L, 2, name); - if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ + if (lua_isnil(L, -1)) { /* module did not set a value? */ lua_pushboolean(L, 1); /* use true as result */ lua_pushvalue(L, -1); /* extra copy to be returned */ lua_setfield(L, 2, name); /* _LOADED[name] = true */ @@ -502,26 +538,31 @@ static int ll_require (lua_State *L) { ** 'module' function ** ======================================================= */ - +#if defined(LUA_COMPAT_MODULE) -static void setfenv (lua_State *L) { +/* +** changes the environment variable of calling function +*/ +static void set_env (lua_State *L) { lua_Debug ar; if (lua_getstack(L, 1, &ar) == 0 || lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ lua_iscfunction(L, -1)) luaL_error(L, LUA_QL("module") " not called from a Lua function"); - lua_pushvalue(L, -2); - lua_setfenv(L, -2); - lua_pop(L, 1); + lua_pushvalue(L, -2); /* copy new environment table to top */ + lua_setupvalue(L, -2, 1); + lua_pop(L, 1); /* remove function */ } static void dooptions (lua_State *L, int n) { int i; for (i = 2; i <= n; i++) { - lua_pushvalue(L, i); /* get option (a function) */ - lua_pushvalue(L, -2); /* module */ - lua_call(L, 1, 0); + if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } } } @@ -543,17 +584,8 @@ static void modinit (lua_State *L, const char *modname) { static int ll_module (lua_State *L) { const char *modname = luaL_checkstring(L, 1); - int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ - if (!lua_istable(L, -1)) { /* not found? */ - lua_pop(L, 1); /* remove previous result */ - /* try global variable (and create one if it does not exist) */ - if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) - return luaL_error(L, "name conflict for module " LUA_QS, modname); - lua_pushvalue(L, -1); - lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ - } + int lastarg = lua_gettop(L); /* last parameter */ + luaL_pushmodule(L, modname, 1); /* get/create module table */ /* check whether table already has a _NAME field */ lua_getfield(L, -1, "_NAME"); if (!lua_isnil(L, -1)) /* is table an initialized module? */ @@ -563,9 +595,9 @@ static int ll_module (lua_State *L) { modinit(L, modname); } lua_pushvalue(L, -1); - setfenv(L); - dooptions(L, loaded - 1); - return 0; + set_env(L); + dooptions(L, lastarg); + return 1; } @@ -576,12 +608,12 @@ static int ll_seeall (lua_State *L) { lua_pushvalue(L, -1); lua_setmetatable(L, 1); } - lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_pushglobaltable(L); lua_setfield(L, -2, "__index"); /* mt.__index = _G */ return 0; } - +#endif /* }====================================================== */ @@ -589,15 +621,30 @@ static int ll_seeall (lua_State *L) { /* auxiliary mark (for internal use) */ #define AUXMARK "\1" -static void setpath (lua_State *L, const char *fieldname, const char *envname, - const char *def) { - const char *path = getenv(envname); + +/* +** return registry.LUA_NOENV as a boolean +*/ +static int noenv (lua_State *L) { + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; +} + + +static void setpath (lua_State *L, const char *fieldname, const char *envname1, + const char *envname2, const char *def) { + const char *path = getenv(envname1); if (path == NULL) /* no environment variable? */ + path = getenv(envname2); /* try alternative name */ + if (path == NULL || noenv(L)) /* no environment variable? */ lua_pushstring(L, def); /* use default */ else { /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ - path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, - LUA_PATHSEP AUXMARK LUA_PATHSEP); + path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, + LUA_PATH_SEP AUXMARK LUA_PATH_SEP); luaL_gsub(L, path, AUXMARK, def); lua_remove(L, -2); } @@ -608,59 +655,71 @@ static void setpath (lua_State *L, const char *fieldname, const char *envname, static const luaL_Reg pk_funcs[] = { {"loadlib", ll_loadlib}, + {"searchpath", ll_searchpath}, +#if defined(LUA_COMPAT_MODULE) {"seeall", ll_seeall}, +#endif {NULL, NULL} }; static const luaL_Reg ll_funcs[] = { +#if defined(LUA_COMPAT_MODULE) {"module", ll_module}, +#endif {"require", ll_require}, {NULL, NULL} }; -static const lua_CFunction loaders[] = - {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; - - -LUALIB_API int luaopen_package (lua_State *L) { +static void createsearcherstable (lua_State *L) { + static const lua_CFunction searchers[] = + {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; int i; - /* create new type _LOADLIB */ - luaL_newmetatable(L, "_LOADLIB"); - lua_pushcfunction(L, gctm); - lua_setfield(L, -2, "__gc"); - /* create `package' table */ - luaL_register(L, LUA_LOADLIBNAME, pk_funcs); -#if defined(LUA_COMPAT_LOADLIB) - lua_getfield(L, -1, "loadlib"); - lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); -#endif - lua_pushvalue(L, -1); - lua_replace(L, LUA_ENVIRONINDEX); - /* create `loaders' table */ - lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); - /* fill it with pre-defined loaders */ - for (i=0; loaders[i] != NULL; i++) { - lua_pushcfunction(L, loaders[i]); + /* create 'searchers' table */ + lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); + /* fill it with pre-defined searchers */ + for (i=0; searchers[i] != NULL; i++) { + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); lua_rawseti(L, -2, i+1); } - lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ - setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ - setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ +} + + +LUAMOD_API int luaopen_package (lua_State *L) { + /* create table CLIBS to keep track of loaded C libraries */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); + lua_createtable(L, 0, 1); /* metatable for CLIBS */ + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ + lua_setmetatable(L, -2); + /* create `package' table */ + luaL_newlib(L, pk_funcs); + createsearcherstable(L); +#if defined(LUA_COMPAT_LOADERS) + lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ + lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ +#endif + lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ + /* set field 'path' */ + setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); + /* set field 'cpath' */ + setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); /* store config information */ - lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" - LUA_EXECDIR "\n" LUA_IGMARK); + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" + LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); lua_setfield(L, -2, "config"); /* set field `loaded' */ - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_setfield(L, -2, "loaded"); /* set field `preload' */ - lua_newtable(L); + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_setfield(L, -2, "preload"); - lua_pushvalue(L, LUA_GLOBALSINDEX); - luaL_register(L, NULL, ll_funcs); /* open lib into global table */ - lua_pop(L, 1); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ return 1; /* return 'package' table */ } diff --git a/src/mod/languages/mod_lua/lua/lobject.c b/src/mod/languages/mod_lua/lua/lobject.c index 4ff50732a4..c152785a5a 100644 --- a/src/mod/languages/mod_lua/lua/lobject.c +++ b/src/mod/languages/mod_lua/lua/lobject.c @@ -1,10 +1,9 @@ /* -** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lobject.c,v 2.58 2013/02/20 14:08:56 roberto Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ -#include #include #include #include @@ -15,6 +14,8 @@ #include "lua.h" +#include "lctype.h" +#include "ldebug.h" #include "ldo.h" #include "lmem.h" #include "lobject.h" @@ -24,7 +25,7 @@ -const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; +LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; /* @@ -33,25 +34,25 @@ const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; ** eeeee != 0 and (xxx) otherwise. */ int luaO_int2fb (unsigned int x) { - int e = 0; /* expoent */ - while (x >= 16) { + int e = 0; /* exponent */ + if (x < 8) return x; + while (x >= 0x10) { x = (x+1) >> 1; e++; } - if (x < 8) return x; - else return ((e+1) << 3) | (cast_int(x) - 8); + return ((e+1) << 3) | (cast_int(x) - 8); } /* converts back */ int luaO_fb2int (int x) { - int e = (x >> 3) & 31; + int e = (x >> 3) & 0x1f; if (e == 0) return x; - else return ((x & 7)+8) << (e - 1); + else return ((x & 7) + 8) << (e - 1); } -int luaO_log2 (unsigned int x) { +int luaO_ceillog2 (unsigned int x) { static const lu_byte log_2[256] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, @@ -62,109 +63,169 @@ int luaO_log2 (unsigned int x) { 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 }; - int l = -1; + int l = 0; + x--; while (x >= 256) { l += 8; x >>= 8; } return l + log_2[x]; - } -int luaO_rawequalObj (const TValue *t1, const TValue *t2) { - if (ttype(t1) != ttype(t2)) return 0; - else switch (ttype(t1)) { - case LUA_TNIL: - return 1; - case LUA_TNUMBER: - return luai_numeq(nvalue(t1), nvalue(t2)); - case LUA_TBOOLEAN: - return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ - case LUA_TLIGHTUSERDATA: - return pvalue(t1) == pvalue(t2); - default: - lua_assert(iscollectable(t1)); - return gcvalue(t1) == gcvalue(t2); +lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { + switch (op) { + case LUA_OPADD: return luai_numadd(NULL, v1, v2); + case LUA_OPSUB: return luai_numsub(NULL, v1, v2); + case LUA_OPMUL: return luai_nummul(NULL, v1, v2); + case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); + case LUA_OPMOD: return luai_nummod(NULL, v1, v2); + case LUA_OPPOW: return luai_numpow(NULL, v1, v2); + case LUA_OPUNM: return luai_numunm(NULL, v1); + default: lua_assert(0); return 0; } } -int luaO_str2d (const char *s, lua_Number *result) { +int luaO_hexavalue (int c) { + if (lisdigit(c)) return c - '0'; + else return ltolower(c) - 'a' + 10; +} + + +#if !defined(lua_strx2number) + +#include + + +static int isneg (const char **s) { + if (**s == '-') { (*s)++; return 1; } + else if (**s == '+') (*s)++; + return 0; +} + + +static lua_Number readhexa (const char **s, lua_Number r, int *count) { + for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */ + r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s))); + (*count)++; + } + return r; +} + + +/* +** convert an hexadecimal numeric string to a number, following +** C99 specification for 'strtod' +*/ +static lua_Number lua_strx2number (const char *s, char **endptr) { + lua_Number r = 0.0; + int e = 0, i = 0; + int neg = 0; /* 1 if number is negative */ + *endptr = cast(char *, s); /* nothing is valid yet */ + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); /* check signal */ + if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ + return 0.0; /* invalid format (no '0x') */ + s += 2; /* skip '0x' */ + r = readhexa(&s, r, &i); /* read integer part */ + if (*s == '.') { + s++; /* skip dot */ + r = readhexa(&s, r, &e); /* read fractional part */ + } + if (i == 0 && e == 0) + return 0.0; /* invalid format (no digit) */ + e *= -4; /* each fractional digit divides value by 2^-4 */ + *endptr = cast(char *, s); /* valid up to here */ + if (*s == 'p' || *s == 'P') { /* exponent part? */ + int exp1 = 0; + int neg1; + s++; /* skip 'p' */ + neg1 = isneg(&s); /* signal */ + if (!lisdigit(cast_uchar(*s))) + goto ret; /* must have at least one digit */ + while (lisdigit(cast_uchar(*s))) /* read exponent */ + exp1 = exp1 * 10 + *(s++) - '0'; + if (neg1) exp1 = -exp1; + e += exp1; + } + *endptr = cast(char *, s); /* valid up to here */ + ret: + if (neg) r = -r; + return l_mathop(ldexp)(r, e); +} + +#endif + + +int luaO_str2d (const char *s, size_t len, lua_Number *result) { char *endptr; - *result = lua_str2number(s, &endptr); - if (endptr == s) return 0; /* conversion failed */ - if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ - *result = cast_num(strtoul(s, &endptr, 16)); - if (*endptr == '\0') return 1; /* most common case */ - while (isspace(cast(unsigned char, *endptr))) endptr++; - if (*endptr != '\0') return 0; /* invalid trailing characters? */ - return 1; + if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ + return 0; + else if (strpbrk(s, "xX")) /* hexa? */ + *result = lua_strx2number(s, &endptr); + else + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* nothing recognized */ + while (lisspace(cast_uchar(*endptr))) endptr++; + return (endptr == s + len); /* OK if no trailing characters */ } -static void pushstr (lua_State *L, const char *str) { - setsvalue2s(L, L->top, luaS_new(L, str)); - incr_top(L); +static void pushstr (lua_State *L, const char *str, size_t l) { + setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); } /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { - int n = 1; - pushstr(L, ""); + int n = 0; for (;;) { const char *e = strchr(fmt, '%'); if (e == NULL) break; - setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); - incr_top(L); + luaD_checkstack(L, 2); /* fmt + item */ + pushstr(L, fmt, e - fmt); switch (*(e+1)) { case 's': { const char *s = va_arg(argp, char *); if (s == NULL) s = "(null)"; - pushstr(L, s); + pushstr(L, s, strlen(s)); break; } case 'c': { - char buff[2]; - buff[0] = cast(char, va_arg(argp, int)); - buff[1] = '\0'; - pushstr(L, buff); + char buff; + buff = cast(char, va_arg(argp, int)); + pushstr(L, &buff, 1); break; } case 'd': { - setnvalue(L->top, cast_num(va_arg(argp, int))); - incr_top(L); + setnvalue(L->top++, cast_num(va_arg(argp, int))); break; } case 'f': { - setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); - incr_top(L); + setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); break; } case 'p': { char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ - sprintf(buff, "%p", va_arg(argp, void *)); - pushstr(L, buff); + int l = sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff, l); break; } case '%': { - pushstr(L, "%"); + pushstr(L, "%", 1); break; } default: { - char buff[3]; - buff[0] = '%'; - buff[1] = *(e+1); - buff[2] = '\0'; - pushstr(L, buff); - break; + luaG_runerror(L, + "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"), + *(e + 1)); } } n += 2; fmt = e+2; } - pushstr(L, fmt); - luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); - L->top -= n; + luaD_checkstack(L, 1); + pushstr(L, fmt, strlen(fmt)); + if (n > 0) luaV_concat(L, n + 1); return svalue(L->top - 1); } @@ -179,36 +240,48 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { } +/* number of chars of a literal string without the ending \0 */ +#define LL(x) (sizeof(x)/sizeof(char) - 1) + +#define RETS "..." +#define PRE "[string \"" +#define POS "\"]" + +#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) + void luaO_chunkid (char *out, const char *source, size_t bufflen) { - if (*source == '=') { - strncpy(out, source+1, bufflen); /* remove first char */ - out[bufflen-1] = '\0'; /* ensures null termination */ + size_t l = strlen(source); + if (*source == '=') { /* 'literal' source */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* truncate it */ + addstr(out, source + 1, bufflen - 1); + *out = '\0'; + } } - else { /* out = "source", or "...source" */ - if (*source == '@') { - size_t l; - source++; /* skip the `@' */ - bufflen -= sizeof(" '...' "); - l = strlen(source); - strcpy(out, ""); - if (l > bufflen) { - source += (l-bufflen); /* get last part of file name */ - strcat(out, "..."); - } - strcat(out, source); + else if (*source == '@') { /* file name */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else { /* add '...' before rest of name */ + addstr(out, RETS, LL(RETS)); + bufflen -= LL(RETS); + memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); } - else { /* out = [string "string"] */ - size_t len = strcspn(source, "\n\r"); /* stop at first newline */ - bufflen -= sizeof(" [string \"...\"] "); - if (len > bufflen) len = bufflen; - strcpy(out, "[string \""); - if (source[len] != '\0') { /* must truncate? */ - strncat(out, source, len); - strcat(out, "..."); - } - else - strcat(out, source); - strcat(out, "\"]"); + } + else { /* string; format as [string "source"] */ + const char *nl = strchr(source, '\n'); /* find first new line (if any) */ + addstr(out, PRE, LL(PRE)); /* add prefix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ + if (l < bufflen && nl == NULL) { /* small one-line source? */ + addstr(out, source, l); /* keep it */ } + else { + if (nl != NULL) l = nl - source; /* stop at first newline */ + if (l > bufflen) l = bufflen; + addstr(out, source, l); + addstr(out, RETS, LL(RETS)); + } + memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); } } + diff --git a/src/mod/languages/mod_lua/lua/lobject.h b/src/mod/languages/mod_lua/lua/lobject.h index f1e447ef3b..dd23b9143c 100644 --- a/src/mod/languages/mod_lua/lua/lobject.h +++ b/src/mod/languages/mod_lua/lua/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ +** $Id: lobject.h,v 2.71 2012/09/11 18:21:44 roberto Exp $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -16,18 +16,52 @@ #include "lua.h" -/* tags for values visible from Lua */ -#define LAST_TAG LUA_TTHREAD - -#define NUM_TAGS (LAST_TAG+1) - - /* ** Extra tags for non-values */ -#define LUA_TPROTO (LAST_TAG+1) -#define LUA_TUPVAL (LAST_TAG+2) -#define LUA_TDEADKEY (LAST_TAG+3) +#define LUA_TPROTO LUA_NUMTAGS +#define LUA_TUPVAL (LUA_NUMTAGS+1) +#define LUA_TDEADKEY (LUA_NUMTAGS+2) + +/* +** number of all possible tags (including LUA_TNONE but excluding DEADKEY) +*/ +#define LUA_TOTALTAGS (LUA_TUPVAL+2) + + +/* +** tags for Tagged Values have the following use of bits: +** bits 0-3: actual tag (a LUA_T* value) +** bits 4-5: variant bits +** bit 6: whether value is collectable +*/ + +#define VARBITS (3 << 4) + + +/* +** LUA_TFUNCTION variants: +** 0 - Lua function +** 1 - light C function +** 2 - regular C function (closure) +*/ + +/* Variant tags for functions */ +#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ +#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ +#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ + + +/* Variant tags for strings */ +#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ +#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ + + +/* Bit mark for collectable types */ +#define BIT_ISCOLLECTABLE (1 << 6) + +/* mark a tag as collectable */ +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) /* @@ -52,120 +86,165 @@ typedef struct GCheader { - /* ** Union of all Lua values */ -typedef union { - GCObject *gc; - void *p; - lua_Number n; - int b; -} Value; +typedef union Value Value; + + +#define numfield lua_Number n; /* numbers */ + /* -** Tagged Values +** Tagged Values. This is the basic representation of values in Lua, +** an actual value plus a tag with its type. */ -#define TValuefields Value value; int tt +#define TValuefields Value value_; int tt_ -typedef struct lua_TValue { - TValuefields; -} TValue; +typedef struct lua_TValue TValue; + + +/* macro defining a nil value */ +#define NILCONSTANT {NULL}, LUA_TNIL + + +#define val_(o) ((o)->value_) +#define num_(o) (val_(o).n) + + +/* raw type tag of a TValue */ +#define rttype(o) ((o)->tt_) + +/* tag with no variants (bits 0-3) */ +#define novariant(x) ((x) & 0x0F) + +/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ +#define ttype(o) (rttype(o) & 0x3F) + +/* type tag of a TValue with no variants (bits 0-3) */ +#define ttypenv(o) (novariant(rttype(o))) /* Macros to test type */ -#define ttisnil(o) (ttype(o) == LUA_TNIL) -#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) -#define ttisstring(o) (ttype(o) == LUA_TSTRING) -#define ttistable(o) (ttype(o) == LUA_TTABLE) -#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) -#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) -#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) -#define ttisthread(o) (ttype(o) == LUA_TTHREAD) -#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) +#define checktag(o,t) (rttype(o) == (t)) +#define checktype(o,t) (ttypenv(o) == (t)) +#define ttisnumber(o) checktag((o), LUA_TNUMBER) +#define ttisnil(o) checktag((o), LUA_TNIL) +#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) +#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) +#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) +#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) +#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) +#define ttislcf(o) checktag((o), LUA_TLCF) +#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) +#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) +#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) + +#define ttisequal(o1,o2) (rttype(o1) == rttype(o2)) /* Macros to access values */ -#define ttype(o) ((o)->tt) -#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) -#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) -#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) -#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define nvalue(o) check_exp(ttisnumber(o), num_(o)) +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) #define tsvalue(o) (&rawtsvalue(o)->tsv) -#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) #define uvalue(o) (&rawuvalue(o)->uv) -#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) -#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) -#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) -#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) +#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) +#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) +#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) +#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) +#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th) +/* a dead value may get the 'gc' field, but cannot access its contents */ +#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) -/* -** for internal debug only -*/ -#define checkconsistency(obj) \ - lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + +#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) + + +/* Macros for internal tests */ +#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) #define checkliveness(g,obj) \ - lua_assert(!iscollectable(obj) || \ - ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) + lua_longassert(!iscollectable(obj) || \ + (righttt(obj) && !isdead(g,gcvalue(obj)))) /* Macros to set values */ -#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) +#define settt_(o,t) ((o)->tt_=(t)) #define setnvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } + { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } + +#define setnilvalue(obj) settt_(obj, LUA_TNIL) + +#define setfvalue(obj,x) \ + { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } #define setpvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } + { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } #define setbvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } + { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } + +#define setgcovalue(L,obj,x) \ + { TValue *io=(obj); GCObject *i_g=(x); \ + val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); } #define setsvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ - checkliveness(G(L),i_o); } + { TValue *io=(obj); \ + TString *x_ = (x); \ + val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \ + checkliveness(G(L),io); } #define setuvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ - checkliveness(G(L),i_o); } + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \ + checkliveness(G(L),io); } #define setthvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ - checkliveness(G(L),i_o); } + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ + checkliveness(G(L),io); } -#define setclvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ - checkliveness(G(L),i_o); } +#define setclLvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \ + checkliveness(G(L),io); } + +#define setclCvalue(L,obj,x) \ + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \ + checkliveness(G(L),io); } #define sethvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ - checkliveness(G(L),i_o); } - -#define setptvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ - checkliveness(G(L),i_o); } + { TValue *io=(obj); \ + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \ + checkliveness(G(L),io); } +#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) #define setobj(L,obj1,obj2) \ - { const TValue *o2=(obj2); TValue *o1=(obj1); \ - o1->value = o2->value; o1->tt=o2->tt; \ - checkliveness(G(L),o1); } + { const TValue *io2=(obj2); TValue *io1=(obj1); \ + io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ + checkliveness(G(L),io1); } /* -** different types of sets, according to destination +** different types of assignments, according to destination */ /* from stack to (same) stack */ @@ -183,47 +262,204 @@ typedef struct lua_TValue { #define setobj2n setobj #define setsvalue2n setsvalue -#define setttype(obj, tt) (ttype(obj) = (tt)) + +/* check whether a number is valid (useful only for NaN trick) */ +#define luai_checknum(L,o,c) { /* empty */ } -#define iscollectable(o) (ttype(o) >= LUA_TSTRING) +/* +** {====================================================== +** NaN Trick +** ======================================================= +*/ +#if defined(LUA_NANTRICK) +/* +** numbers are represented in the 'd_' field. All other values have the +** value (NNMARK | tag) in 'tt__'. A number with such pattern would be +** a "signaled NaN", which is never generated by regular operations by +** the CPU (nor by 'strtod') +*/ + +/* allows for external implementation for part of the trick */ +#if !defined(NNMARK) /* { */ + + +#if !defined(LUA_IEEEENDIAN) +#error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN' +#endif + + +#define NNMARK 0x7FF7A500 +#define NNMASK 0x7FFFFF00 + +#undef TValuefields +#undef NILCONSTANT + +#if (LUA_IEEEENDIAN == 0) /* { */ + +/* little endian */ +#define TValuefields \ + union { struct { Value v__; int tt__; } i; double d__; } u +#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}} +/* field-access macros */ +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) + +#else /* }{ */ + +/* big endian */ +#define TValuefields \ + union { struct { int tt__; Value v__; } i; double d__; } u +#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}} +/* field-access macros */ +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) + +#endif /* } */ + +#endif /* } */ + + +/* correspondence with standard representation */ +#undef val_ +#define val_(o) v_(o) +#undef num_ +#define num_(o) d_(o) + + +#undef numfield +#define numfield /* no such field; numbers are the entire struct */ + +/* basic check to distinguish numbers from non-numbers */ +#undef ttisnumber +#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK) + +#define tag2tt(t) (NNMARK | (t)) + +#undef rttype +#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff) + +#undef settt_ +#define settt_(o,t) (tt_(o) = tag2tt(t)) + +#undef setnvalue +#define setnvalue(obj,x) \ + { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); } + +#undef setobj +#define setobj(L,obj1,obj2) \ + { const TValue *o2_=(obj2); TValue *o1_=(obj1); \ + o1_->u = o2_->u; \ + checkliveness(G(L),o1_); } + + +/* +** these redefinitions are not mandatory, but these forms are more efficient +*/ + +#undef checktag +#undef checktype +#define checktag(o,t) (tt_(o) == tag2tt(t)) +#define checktype(o,t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS)) + +#undef ttisequal +#define ttisequal(o1,o2) \ + (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2))) + + +#undef luai_checknum +#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } + +#endif +/* }====================================================== */ + + + +/* +** {====================================================== +** types and prototypes +** ======================================================= +*/ + + +union Value { + GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + int b; /* booleans */ + lua_CFunction f; /* light C functions */ + numfield /* numbers */ +}; + + +struct lua_TValue { + TValuefields; +}; typedef TValue *StkId; /* index to stack elements */ + + /* -** String headers for string table +** Header for string value; string bytes follow the end of this structure */ typedef union TString { L_Umaxalign dummy; /* ensures maximum alignment for strings */ struct { CommonHeader; - lu_byte reserved; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ unsigned int hash; - size_t len; + size_t len; /* number of characters in string */ } tsv; } TString; +/* get the actual string (array of bytes) from a TString */ #define getstr(ts) cast(const char *, (ts) + 1) + +/* get the actual string (array of bytes) from a Lua value */ #define svalue(o) getstr(rawtsvalue(o)) - +/* +** Header for userdata; memory area follows the end of this structure +*/ typedef union Udata { L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ struct { CommonHeader; struct Table *metatable; struct Table *env; - size_t len; + size_t len; /* number of bytes */ } uv; } Udata; +/* +** Description of an upvalue for function prototypes +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ +} Upvaldesc; + + +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + /* ** Function Prototypes @@ -233,11 +469,12 @@ typedef struct Proto { TValue *k; /* constants used by the function */ Instruction *code; struct Proto **p; /* functions defined inside the function */ - int *lineinfo; /* map from opcodes to source lines */ - struct LocVar *locvars; /* information about local variables */ - TString **upvalues; /* upvalue names */ - TString *source; - int sizeupvalues; + int *lineinfo; /* map from opcodes to source lines (debug information) */ + LocVar *locvars; /* information about local variables (debug information) */ + Upvaldesc *upvalues; /* upvalue information */ + union Closure *cache; /* last created closure with this prototype */ + TString *source; /* used for debug information */ + int sizeupvalues; /* size of 'upvalues' */ int sizek; /* size of `k' */ int sizecode; int sizelineinfo; @@ -246,31 +483,16 @@ typedef struct Proto { int linedefined; int lastlinedefined; GCObject *gclist; - lu_byte nups; /* number of upvalues */ - lu_byte numparams; + lu_byte numparams; /* number of fixed parameters */ lu_byte is_vararg; - lu_byte maxstacksize; + lu_byte maxstacksize; /* maximum stack used by this function */ } Proto; -/* masks for new-style vararg */ -#define VARARG_HASARG 1 -#define VARARG_ISVARARG 2 -#define VARARG_NEEDSARG 4 - - -typedef struct LocVar { - TString *varname; - int startpc; /* first point where variable is active */ - int endpc; /* first point where variable is dead */ -} LocVar; - - /* -** Upvalues +** Lua Upvalues */ - typedef struct UpVal { CommonHeader; TValue *v; /* points to stack or to its own value */ @@ -289,20 +511,19 @@ typedef struct UpVal { */ #define ClosureHeader \ - CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ - struct Table *env + CommonHeader; lu_byte nupvalues; GCObject *gclist typedef struct CClosure { ClosureHeader; lua_CFunction f; - TValue upvalue[1]; + TValue upvalue[1]; /* list of upvalues */ } CClosure; typedef struct LClosure { ClosureHeader; struct Proto *p; - UpVal *upvals[1]; + UpVal *upvals[1]; /* list of upvalues */ } LClosure; @@ -312,8 +533,9 @@ typedef union Closure { } Closure; -#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) -#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) +#define isLfunction(o) ttisLclosure(o) + +#define getproto(o) (clLvalue(o)->p) /* @@ -337,7 +559,7 @@ typedef struct Node { typedef struct Table { CommonHeader; - lu_byte flags; /* 1<

lsizenode)) +/* +** (address of) a fixed nil value +*/ #define luaO_nilobject (&luaO_nilobject_) -LUAI_DATA const TValue luaO_nilobject_; -#define ceillog2(x) (luaO_log2((x)-1) + 1) +LUAI_DDEC const TValue luaO_nilobject_; + -LUAI_FUNC int luaO_log2 (unsigned int x); LUAI_FUNC int luaO_int2fb (unsigned int x); LUAI_FUNC int luaO_fb2int (int x); -LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); -LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); +LUAI_FUNC int luaO_ceillog2 (unsigned int x); +LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2); +LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); +LUAI_FUNC int luaO_hexavalue (int c); LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp); LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); diff --git a/src/mod/languages/mod_lua/lua/lopcodes.c b/src/mod/languages/mod_lua/lua/lopcodes.c index 4cc745230b..ef73692754 100644 --- a/src/mod/languages/mod_lua/lua/lopcodes.c +++ b/src/mod/languages/mod_lua/lua/lopcodes.c @@ -1,5 +1,6 @@ /* -** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lopcodes.c,v 1.49 2012/05/14 13:34:18 roberto Exp $ +** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -13,15 +14,16 @@ /* ORDER OP */ -const char *const luaP_opnames[NUM_OPCODES+1] = { +LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { "MOVE", "LOADK", + "LOADKX", "LOADBOOL", "LOADNIL", "GETUPVAL", - "GETGLOBAL", + "GETTABUP", "GETTABLE", - "SETGLOBAL", + "SETTABUP", "SETUPVAL", "SETTABLE", "NEWTABLE", @@ -47,27 +49,29 @@ const char *const luaP_opnames[NUM_OPCODES+1] = { "RETURN", "FORLOOP", "FORPREP", + "TFORCALL", "TFORLOOP", "SETLIST", - "CLOSE", "CLOSURE", "VARARG", + "EXTRAARG", NULL }; #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) -const lu_byte luaP_opmodes[NUM_OPCODES] = { +LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { /* T A B C mode opcode */ - opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ - ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ - ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ @@ -86,17 +90,18 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ - ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ - ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ - ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ + ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ }; diff --git a/src/mod/languages/mod_lua/lua/lopcodes.h b/src/mod/languages/mod_lua/lua/lopcodes.h index 41224d6ee1..07d2b3f39a 100644 --- a/src/mod/languages/mod_lua/lua/lopcodes.h +++ b/src/mod/languages/mod_lua/lua/lopcodes.h @@ -1,5 +1,5 @@ /* -** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lopcodes.h,v 1.142 2011/07/15 12:50:29 roberto Exp $ ** Opcodes for Lua virtual machine ** See Copyright Notice in lua.h */ @@ -17,6 +17,7 @@ `A' : 8 bits `B' : 9 bits `C' : 9 bits + 'Ax' : 26 bits ('A', 'B', and 'C' together) `Bx' : 18 bits (`B' and `C' together) `sBx' : signed Bx @@ -28,7 +29,7 @@ ===========================================================================*/ -enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ +enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ /* @@ -38,6 +39,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ #define SIZE_B 9 #define SIZE_Bx (SIZE_C + SIZE_B) #define SIZE_A 8 +#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) #define SIZE_OP 6 @@ -46,6 +48,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ #define POS_C (POS_A + SIZE_A) #define POS_B (POS_C + SIZE_C) #define POS_Bx POS_C +#define POS_Ax POS_A /* @@ -61,6 +64,12 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ #define MAXARG_sBx MAX_INT #endif +#if SIZE_Ax < LUAI_BITSINT-1 +#define MAXARG_Ax ((1<>POS_A) & MASK1(SIZE_A,0))) -#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ - ((cast(Instruction, u)<>pos) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<>POS_B) & MASK1(SIZE_B,0))) -#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ - ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) -#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ - ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) -#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ - ((cast(Instruction, b)<= R(A) + 1 */ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ -OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ -OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ +OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ +OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ -OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ -OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ +OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ @@ -197,39 +212,44 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) =) R(A)*/ -OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ -OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */ + +OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ } OpCode; -#define NUM_OPCODES (cast(int, OP_VARARG) + 1) +#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1) /*=========================================================================== Notes: - (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, - and can be 0: OP_CALL then sets `top' to last_result+1, so - next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. + (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is + set to last_result+1, so next open instruction (OP_CALL, OP_RETURN, + OP_SETLIST) may use `top'. (*) In OP_VARARG, if (B == 0) then use actual number of varargs and - set top (like in OP_CALL with C == 0). + set top (like in OP_CALL with C == 0). - (*) In OP_RETURN, if (B == 0) then return up to `top' + (*) In OP_RETURN, if (B == 0) then return up to `top'. - (*) In OP_SETLIST, if (B == 0) then B = `top'; - if (C == 0) then next `instruction' is real C + (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next + 'instruction' is EXTRAARG(real C). + + (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. (*) For comparisons, A specifies what condition the test should accept - (true or false). + (true or false). + + (*) All `skips' (pc++) assume that next instruction is a jump. - (*) All `skips' (pc++) assume that next instruction is a jump ===========================================================================*/ @@ -239,8 +259,8 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ ** bits 2-3: C arg mode ** bits 4-5: B arg mode ** bit 6: instruction set register A -** bit 7: operator is a test -*/ +** bit 7: operator is a test (next instruction must be a jump) +*/ enum OpArgMask { OpArgN, /* argument is not used */ @@ -249,7 +269,7 @@ enum OpArgMask { OpArgK /* argument is a constant or register/constant */ }; -LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; +LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES]; #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) @@ -258,7 +278,7 @@ LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; #define testTMode(m) (luaP_opmodes[m] & (1 << 7)) -LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ +LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ /* number of list items to accumulate before a SETLIST instruction */ diff --git a/src/mod/languages/mod_lua/lua/loslib.c b/src/mod/languages/mod_lua/lua/loslib.c index da06a572ac..5170fd0d0f 100644 --- a/src/mod/languages/mod_lua/lua/loslib.c +++ b/src/mod/languages/mod_lua/lua/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ +** $Id: loslib.c,v 1.40 2012/10/19 15:54:02 roberto Exp $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -20,37 +20,85 @@ #include "lualib.h" -static int os_pushresult (lua_State *L, int i, const char *filename) { - int en = errno; /* calls to Lua API may change this value */ - if (i) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushnil(L); - lua_pushfstring(L, "%s: %s", filename, strerror(en)); - lua_pushinteger(L, en); - return 3; - } -} +/* +** list of valid conversion specifiers for the 'strftime' function +*/ +#if !defined(LUA_STRFTIMEOPTIONS) + +#if !defined(LUA_USE_POSIX) +#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } +#else +#define LUA_STRFTIMEOPTIONS \ + { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \ + "", "E", "cCxXyY", \ + "O", "deHImMSuUVwWy" } +#endif + +#endif + + + +/* +** By default, Lua uses tmpnam except when POSIX is available, where it +** uses mkstemp. +*/ +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#elif !defined(lua_tmpnam) + +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } + +#endif + + +/* +** By default, Lua uses gmtime/localtime, except when POSIX is available, +** where it uses gmtime_r/localtime_r +*/ +#if defined(LUA_USE_GMTIME_R) + +#define l_gmtime(t,r) gmtime_r(t,r) +#define l_localtime(t,r) localtime_r(t,r) + +#elif !defined(l_gmtime) + +#define l_gmtime(t,r) ((void)r, gmtime(t)) +#define l_localtime(t,r) ((void)r, localtime(t)) + +#endif + static int os_execute (lua_State *L) { - lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); - return 1; + const char *cmd = luaL_optstring(L, 1, NULL); + int stat = system(cmd); + if (cmd != NULL) + return luaL_execresult(L, stat); + else { + lua_pushboolean(L, stat); /* true if there is a shell */ + return 1; + } } static int os_remove (lua_State *L) { const char *filename = luaL_checkstring(L, 1); - return os_pushresult(L, remove(filename) == 0, filename); + return luaL_fileresult(L, remove(filename) == 0, filename); } static int os_rename (lua_State *L) { const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); - return os_pushresult(L, rename(fromname, toname) == 0, fromname); + return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); } @@ -107,11 +155,10 @@ static int getboolfield (lua_State *L, const char *key) { static int getfield (lua_State *L, const char *key, int d) { - int res; + int res, isnum; lua_getfield(L, -1, key); - if (lua_isnumber(L, -1)) - res = (int)lua_tointeger(L, -1); - else { + res = (int)lua_tointegerx(L, -1, &isnum); + if (!isnum) { if (d < 0) return luaL_error(L, "field " LUA_QS " missing in date table", key); res = d; @@ -121,16 +168,40 @@ static int getfield (lua_State *L, const char *key, int d) { } +static const char *checkoption (lua_State *L, const char *conv, char *buff) { + static const char *const options[] = LUA_STRFTIMEOPTIONS; + unsigned int i; + for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) { + if (*conv != '\0' && strchr(options[i], *conv) != NULL) { + buff[1] = *conv; + if (*options[i + 1] == '\0') { /* one-char conversion specifier? */ + buff[2] = '\0'; /* end buffer */ + return conv + 1; + } + else if (*(conv + 1) != '\0' && + strchr(options[i + 1], *(conv + 1)) != NULL) { + buff[2] = *(conv + 1); /* valid two-char conversion specifier */ + buff[3] = '\0'; /* end buffer */ + return conv + 2; + } + } + } + luaL_argerror(L, 1, + lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); + return conv; /* to avoid warnings */ +} + + static int os_date (lua_State *L) { const char *s = luaL_optstring(L, 1, "%c"); time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); - struct tm *stm; + struct tm tmr, *stm; if (*s == '!') { /* UTC? */ - stm = gmtime(&t); + stm = l_gmtime(&t, &tmr); s++; /* skip `!' */ } else - stm = localtime(&t); + stm = l_localtime(&t, &tmr); if (stm == NULL) /* invalid date? */ lua_pushnil(L); else if (strcmp(s, "*t") == 0) { @@ -146,17 +217,17 @@ static int os_date (lua_State *L) { setboolfield(L, "isdst", stm->tm_isdst); } else { - char cc[3]; + char cc[4]; luaL_Buffer b; - cc[0] = '%'; cc[2] = '\0'; + cc[0] = '%'; luaL_buffinit(L, &b); - for (; *s; s++) { - if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ - luaL_addchar(&b, *s); + while (*s) { + if (*s != '%') /* no conversion specifier? */ + luaL_addchar(&b, *s++); else { size_t reslen; char buff[200]; /* should be big enough for any conversion result */ - cc[1] = *(++s); + s = checkoption(L, s + 1, cc); reslen = strftime(buff, sizeof(buff), cc, stm); luaL_addlstring(&b, buff, reslen); } @@ -214,9 +285,18 @@ static int os_setlocale (lua_State *L) { static int os_exit (lua_State *L) { - exit(luaL_optint(L, 1, EXIT_SUCCESS)); + int status; + if (lua_isboolean(L, 1)) + status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); + else + status = luaL_optint(L, 1, EXIT_SUCCESS); + if (lua_toboolean(L, 2)) + lua_close(L); + if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ + return 0; } + static const luaL_Reg syslib[] = { {"clock", os_clock}, {"date", os_date}, @@ -236,8 +316,8 @@ static const luaL_Reg syslib[] = { -LUALIB_API int luaopen_os (lua_State *L) { - luaL_register(L, LUA_OSLIBNAME, syslib); +LUAMOD_API int luaopen_os (lua_State *L) { + luaL_newlib(L, syslib); return 1; } diff --git a/src/mod/languages/mod_lua/lua/lparser.c b/src/mod/languages/mod_lua/lua/lparser.c index 1e2a9a88b7..d8f5b4ffc5 100644 --- a/src/mod/languages/mod_lua/lua/lparser.c +++ b/src/mod/languages/mod_lua/lua/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ +** $Id: lparser.c,v 2.130 2013/02/06 13:37:39 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -27,11 +27,13 @@ +/* maximum number of local variables per function (must be smaller + than 250, due to the bytecode format) */ +#define MAXVARS 200 + + #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) -#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) - -#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) /* @@ -39,10 +41,11 @@ */ typedef struct BlockCnt { struct BlockCnt *previous; /* chain */ - int breaklist; /* list of jumps out of this loop */ - lu_byte nactvar; /* # active locals outside the breakable structure */ + short firstlabel; /* index of first label in this block */ + short firstgoto; /* index of first pending goto in this block */ + lu_byte nactvar; /* # active locals outside the block */ lu_byte upval; /* true if some variable in the block is an upvalue */ - lu_byte isbreakable; /* true if `block' is a loop */ + lu_byte isloop; /* true if `block' is a loop */ } BlockCnt; @@ -50,11 +53,13 @@ typedef struct BlockCnt { /* ** prototypes for recursive non-terminal functions */ -static void chunk (LexState *ls); +static void statement (LexState *ls); static void expr (LexState *ls, expdesc *v); static void anchor_token (LexState *ls) { + /* last token from outer function must be EOS */ + lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { TString *ts = ls->t.seminfo.ts; luaX_newstring(ls, getstr(ts), ts->tsv.len); @@ -62,18 +67,34 @@ static void anchor_token (LexState *ls) { } -static void error_expected (LexState *ls, int token) { - luaX_syntaxerror(ls, - luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); +/* semantic error */ +static l_noret semerror (LexState *ls, const char *msg) { + ls->t.token = 0; /* remove 'near to' from final message */ + luaX_syntaxerror(ls, msg); } -static void errorlimit (FuncState *fs, int limit, const char *what) { - const char *msg = (fs->f->linedefined == 0) ? - luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : - luaO_pushfstring(fs->L, "function at line %d has more than %d %s", - fs->f->linedefined, limit, what); - luaX_lexerror(fs->ls, msg, 0); +static l_noret error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); +} + + +static l_noret errorlimit (FuncState *fs, int limit, const char *what) { + lua_State *L = fs->ls->L; + const char *msg; + int line = fs->f->linedefined; + const char *where = (line == 0) + ? "main function" + : luaO_pushfstring(L, "function at line %d", line); + msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", + what, limit, where); + luaX_syntaxerror(fs->ls, msg); +} + + +static void checklimit (FuncState *fs, int v, int l, const char *what) { + if (v > l) errorlimit(fs, l, what); } @@ -91,6 +112,7 @@ static void check (LexState *ls, int c) { error_expected(ls, c); } + static void checknext (LexState *ls, int c) { check(ls, c); luaX_next(ls); @@ -107,7 +129,7 @@ static void check_match (LexState *ls, int what, int who, int where) { error_expected(ls, what); else { luaX_syntaxerror(ls, luaO_pushfstring(ls->L, - LUA_QS " expected (to close " LUA_QS " at line %d)", + "%s expected (to close %s at line %d)", luaX_token2str(ls, what), luaX_token2str(ls, who), where)); } } @@ -126,7 +148,7 @@ static TString *str_checkname (LexState *ls) { static void init_exp (expdesc *e, expkind k, int i) { e->f = e->t = NO_JUMP; e->k = k; - e->u.s.info = i; + e->u.info = i; } @@ -135,7 +157,7 @@ static void codestring (LexState *ls, expdesc *e, TString *s) { } -static void checkname(LexState *ls, expdesc *e) { +static void checkname (LexState *ls, expdesc *e) { codestring(ls, e, str_checkname(ls)); } @@ -145,7 +167,7 @@ static int registerlocalvar (LexState *ls, TString *varname) { Proto *f = fs->f; int oldsize = f->sizelocvars; luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, - LocVar, SHRT_MAX, "too many local variables"); + LocVar, SHRT_MAX, "local variables"); while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; f->locvars[fs->nlocvars].varname = varname; luaC_objbarrier(ls->L, f, varname); @@ -153,14 +175,30 @@ static int registerlocalvar (LexState *ls, TString *varname) { } -#define new_localvarliteral(ls,v,n) \ - new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) - - -static void new_localvar (LexState *ls, TString *name, int n) { +static void new_localvar (LexState *ls, TString *name) { FuncState *fs = ls->fs; - luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); - fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); + Dyndata *dyd = ls->dyd; + int reg = registerlocalvar(ls, name); + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + MAXVARS, "local variables"); + luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, + dyd->actvar.size, Vardesc, MAX_INT, "local variables"); + dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); +} + + +static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { + new_localvar(ls, luaX_newstring(ls, name, sz)); +} + +#define new_localvarliteral(ls,v) \ + new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) + + +static LocVar *getlocvar (FuncState *fs, int i) { + int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; + lua_assert(idx < fs->nlocvars); + return &fs->f->locvars[idx]; } @@ -168,77 +206,88 @@ static void adjustlocalvars (LexState *ls, int nvars) { FuncState *fs = ls->fs; fs->nactvar = cast_byte(fs->nactvar + nvars); for (; nvars; nvars--) { - getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; + getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; } } -static void removevars (LexState *ls, int tolevel) { - FuncState *fs = ls->fs; +static void removevars (FuncState *fs, int tolevel) { + fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); while (fs->nactvar > tolevel) - getlocvar(fs, --fs->nactvar).endpc = fs->pc; + getlocvar(fs, --fs->nactvar)->endpc = fs->pc; } -static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { +static int searchupvalue (FuncState *fs, TString *name) { int i; + Upvaldesc *up = fs->f->upvalues; + for (i = 0; i < fs->nups; i++) { + if (luaS_eqstr(up[i].name, name)) return i; + } + return -1; /* not found */ +} + + +static int newupvalue (FuncState *fs, TString *name, expdesc *v) { Proto *f = fs->f; int oldsize = f->sizeupvalues; - for (i=0; inups; i++) { - if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { - lua_assert(f->upvalues[i] == name); - return i; - } - } - /* new one */ - luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); - luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, - TString *, MAX_INT, ""); - while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; - f->upvalues[f->nups] = name; - luaC_objbarrier(fs->L, f, name); - lua_assert(v->k == VLOCAL || v->k == VUPVAL); - fs->upvalues[f->nups].k = cast_byte(v->k); - fs->upvalues[f->nups].info = cast_byte(v->u.s.info); - return f->nups++; + checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, MAXUPVAL, "upvalues"); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; + f->upvalues[fs->nups].instack = (v->k == VLOCAL); + f->upvalues[fs->nups].idx = cast_byte(v->u.info); + f->upvalues[fs->nups].name = name; + luaC_objbarrier(fs->ls->L, f, name); + return fs->nups++; } static int searchvar (FuncState *fs, TString *n) { int i; - for (i=fs->nactvar-1; i >= 0; i--) { - if (n == getlocvar(fs, i).varname) + for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { + if (luaS_eqstr(n, getlocvar(fs, i)->varname)) return i; } return -1; /* not found */ } +/* + Mark block where variable at given level was defined + (to emit close instructions later). +*/ static void markupval (FuncState *fs, int level) { BlockCnt *bl = fs->bl; - while (bl && bl->nactvar > level) bl = bl->previous; - if (bl) bl->upval = 1; + while (bl->nactvar > level) bl = bl->previous; + bl->upval = 1; } +/* + Find variable with given name 'n'. If it is an upvalue, add this + upvalue into all intermediate functions. +*/ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { - if (fs == NULL) { /* no more levels? */ - init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ - return VGLOBAL; - } + if (fs == NULL) /* no more levels? */ + return VVOID; /* default is global */ else { - int v = searchvar(fs, n); /* look up at current level */ - if (v >= 0) { - init_exp(var, VLOCAL, v); + int v = searchvar(fs, n); /* look up locals at current level */ + if (v >= 0) { /* found? */ + init_exp(var, VLOCAL, v); /* variable is local */ if (!base) markupval(fs, v); /* local will be used as an upval */ return VLOCAL; } - else { /* not found at current level; try upper one */ - if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) - return VGLOBAL; - var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ - var->k = VUPVAL; /* upvalue in this level */ + else { /* not found as local at current level; try upvalues */ + int idx = searchupvalue(fs, n); /* try existing upvalues */ + if (idx < 0) { /* not found? */ + if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ + return VVOID; /* not found; is a global */ + /* else was LOCAL or UPVAL */ + idx = newupvalue(fs, n, var); /* will be a new upvalue */ + } + init_exp(var, VUPVAL, idx); return VUPVAL; } } @@ -248,8 +297,13 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { static void singlevar (LexState *ls, expdesc *var) { TString *varname = str_checkname(ls); FuncState *fs = ls->fs; - if (singlevaraux(fs, varname, var, 1) == VGLOBAL) - var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ + if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ + expdesc key; + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + lua_assert(var->k == VLOCAL || var->k == VUPVAL); + codestring(ls, &key, varname); /* key is variable name */ + luaK_indexed(fs, var, &key); /* env[varname] */ + } } @@ -274,18 +328,118 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { static void enterlevel (LexState *ls) { - if (++ls->L->nCcalls > LUAI_MAXCCALLS) - luaX_lexerror(ls, "chunk has too many syntax levels", 0); + lua_State *L = ls->L; + ++L->nCcalls; + checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); } #define leavelevel(ls) ((ls)->L->nCcalls--) -static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { - bl->breaklist = NO_JUMP; - bl->isbreakable = isbreakable; +static void closegoto (LexState *ls, int g, Labeldesc *label) { + int i; + FuncState *fs = ls->fs; + Labellist *gl = &ls->dyd->gt; + Labeldesc *gt = &gl->arr[g]; + lua_assert(luaS_eqstr(gt->name, label->name)); + if (gt->nactvar < label->nactvar) { + TString *vname = getlocvar(fs, gt->nactvar)->varname; + const char *msg = luaO_pushfstring(ls->L, + " at line %d jumps into the scope of local " LUA_QS, + getstr(gt->name), gt->line, getstr(vname)); + semerror(ls, msg); + } + luaK_patchlist(fs, gt->pc, label->pc); + /* remove goto from pending list */ + for (i = g; i < gl->n - 1; i++) + gl->arr[i] = gl->arr[i + 1]; + gl->n--; +} + + +/* +** try to close a goto with existing labels; this solves backward jumps +*/ +static int findlabel (LexState *ls, int g) { + int i; + BlockCnt *bl = ls->fs->bl; + Dyndata *dyd = ls->dyd; + Labeldesc *gt = &dyd->gt.arr[g]; + /* check labels in current block for a match */ + for (i = bl->firstlabel; i < dyd->label.n; i++) { + Labeldesc *lb = &dyd->label.arr[i]; + if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ + if (gt->nactvar > lb->nactvar && + (bl->upval || dyd->label.n > bl->firstlabel)) + luaK_patchclose(ls->fs, gt->pc, lb->nactvar); + closegoto(ls, g, lb); /* close it */ + return 1; + } + } + return 0; /* label not found; cannot close goto */ +} + + +static int newlabelentry (LexState *ls, Labellist *l, TString *name, + int line, int pc) { + int n = l->n; + luaM_growvector(ls->L, l->arr, n, l->size, + Labeldesc, SHRT_MAX, "labels/gotos"); + l->arr[n].name = name; + l->arr[n].line = line; + l->arr[n].nactvar = ls->fs->nactvar; + l->arr[n].pc = pc; + l->n++; + return n; +} + + +/* +** check whether new label 'lb' matches any pending gotos in current +** block; solves forward jumps +*/ +static void findgotos (LexState *ls, Labeldesc *lb) { + Labellist *gl = &ls->dyd->gt; + int i = ls->fs->bl->firstgoto; + while (i < gl->n) { + if (luaS_eqstr(gl->arr[i].name, lb->name)) + closegoto(ls, i, lb); + else + i++; + } +} + + +/* +** "export" pending gotos to outer level, to check them against +** outer labels; if the block being exited has upvalues, and +** the goto exits the scope of any variable (which can be the +** upvalue), close those variables being exited. +*/ +static void movegotosout (FuncState *fs, BlockCnt *bl) { + int i = bl->firstgoto; + Labellist *gl = &fs->ls->dyd->gt; + /* correct pending gotos to current block and try to close it + with visible labels */ + while (i < gl->n) { + Labeldesc *gt = &gl->arr[i]; + if (gt->nactvar > bl->nactvar) { + if (bl->upval) + luaK_patchclose(fs, gt->pc, bl->nactvar); + gt->nactvar = bl->nactvar; + } + if (!findlabel(fs->ls, i)) + i++; /* move to next one */ + } +} + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { + bl->isloop = isloop; bl->nactvar = fs->nactvar; + bl->firstlabel = fs->ls->dyd->label.n; + bl->firstgoto = fs->ls->dyd->gt.n; bl->upval = 0; bl->previous = fs->bl; fs->bl = bl; @@ -293,63 +447,108 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { } +/* +** create a label named "break" to resolve break statements +*/ +static void breaklabel (LexState *ls) { + TString *n = luaS_new(ls->L, "break"); + int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); + findgotos(ls, &ls->dyd->label.arr[l]); +} + +/* +** generates an error for an undefined 'goto'; choose appropriate +** message when label name is a reserved word (which can only be 'break') +*/ +static l_noret undefgoto (LexState *ls, Labeldesc *gt) { + const char *msg = isreserved(gt->name) + ? "<%s> at line %d not inside a loop" + : "no visible label " LUA_QS " for at line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); + semerror(ls, msg); +} + + static void leaveblock (FuncState *fs) { BlockCnt *bl = fs->bl; + LexState *ls = fs->ls; + if (bl->previous && bl->upval) { + /* create a 'jump to here' to close upvalues */ + int j = luaK_jump(fs); + luaK_patchclose(fs, j, bl->nactvar); + luaK_patchtohere(fs, j); + } + if (bl->isloop) + breaklabel(ls); /* close pending breaks */ fs->bl = bl->previous; - removevars(fs->ls, bl->nactvar); - if (bl->upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); - /* a block either controls scope or breaks (never both) */ - lua_assert(!bl->isbreakable || !bl->upval); + removevars(fs, bl->nactvar); lua_assert(bl->nactvar == fs->nactvar); fs->freereg = fs->nactvar; /* free registers */ - luaK_patchtohere(fs, bl->breaklist); + ls->dyd->label.n = bl->firstlabel; /* remove local labels */ + if (bl->previous) /* inner block? */ + movegotosout(fs, bl); /* update pending gotos to outer block */ + else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ + undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ } -static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { - FuncState *fs = ls->fs; - Proto *f = fs->f; - int oldsize = f->sizep; - int i; - luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, - MAXARG_Bx, "constant table overflow"); - while (oldsize < f->sizep) f->p[oldsize++] = NULL; - f->p[fs->np++] = func->f; - luaC_objbarrier(ls->L, f, func->f); - init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); - for (i=0; if->nups; i++) { - OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; - luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); - } -} - - -static void open_func (LexState *ls, FuncState *fs) { +/* +** adds a new prototype into list of prototypes +*/ +static Proto *addprototype (LexState *ls) { + Proto *clp; lua_State *L = ls->L; - Proto *f = luaF_newproto(L); - fs->f = f; + FuncState *fs = ls->fs; + Proto *f = fs->f; /* prototype of current function */ + if (fs->np >= f->sizep) { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + } + f->p[fs->np++] = clp = luaF_newproto(L); + luaC_objbarrier(L, f, clp); + return clp; +} + + +/* +** codes instruction to create new closure in parent function. +** The OP_CLOSURE instruction must use the last available register, +** so that, if it invokes the GC, the GC knows which registers +** are in use at that time. +*/ +static void codeclosure (LexState *ls, expdesc *v) { + FuncState *fs = ls->fs->prev; + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ +} + + +static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { + lua_State *L = ls->L; + Proto *f; fs->prev = ls->fs; /* linked list of funcstates */ fs->ls = ls; - fs->L = L; ls->fs = fs; fs->pc = 0; - fs->lasttarget = -1; + fs->lasttarget = 0; fs->jpc = NO_JUMP; fs->freereg = 0; fs->nk = 0; fs->np = 0; + fs->nups = 0; fs->nlocvars = 0; fs->nactvar = 0; + fs->firstlocal = ls->dyd->actvar.n; fs->bl = NULL; + f = fs->f; f->source = ls->source; f->maxstacksize = 2; /* registers 0/1 are always valid */ - fs->h = luaH_new(L, 0, 0); - /* anchor table of constants and prototype (to avoid being collected) */ + fs->h = luaH_new(L); + /* anchor table of constants (to avoid being collected) */ sethvalue2s(L, L->top, fs->h); incr_top(L); - setptvalue2s(L, L->top, f); - incr_top(L); + enterblock(fs, bl, 0); } @@ -357,8 +556,8 @@ static void close_func (LexState *ls) { lua_State *L = ls->L; FuncState *fs = ls->fs; Proto *f = fs->f; - removevars(ls, 0); luaK_ret(fs, 0, 0); /* final return */ + leaveblock(fs); luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); f->sizecode = fs->pc; luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); @@ -369,32 +568,14 @@ static void close_func (LexState *ls) { f->sizep = fs->np; luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); f->sizelocvars = fs->nlocvars; - luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); - f->sizeupvalues = f->nups; - lua_assert(luaG_checkcode(f)); + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + f->sizeupvalues = fs->nups; lua_assert(fs->bl == NULL); ls->fs = fs->prev; - L->top -= 2; /* remove table and prototype from the stack */ - /* last token read was anchored in defunct function; must reanchor it */ - if (fs) anchor_token(ls); -} - - -Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { - struct LexState lexstate; - struct FuncState funcstate; - lexstate.buff = buff; - luaX_setinput(L, &lexstate, z, luaS_new(L, name)); - open_func(&lexstate, &funcstate); - funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ - luaX_next(&lexstate); /* read first token */ - chunk(&lexstate); - check(&lexstate, TK_EOS); - close_func(&lexstate); - lua_assert(funcstate.prev == NULL); - lua_assert(funcstate.f->nups == 0); - lua_assert(lexstate.fs == NULL); - return funcstate.f; + /* last token read was anchored in defunct function; must re-anchor it */ + anchor_token(ls); + L->top--; /* pop table of constants */ + luaC_checkGC(L); } @@ -404,11 +585,39 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { /*============================================================*/ -static void field (LexState *ls, expdesc *v) { - /* field -> ['.' | ':'] NAME */ +/* +** check whether current token is in the follow set of a block. +** 'until' closes syntactical blocks, but do not close scope, +** so it handled in separate. +*/ +static int block_follow (LexState *ls, int withuntil) { + switch (ls->t.token) { + case TK_ELSE: case TK_ELSEIF: + case TK_END: case TK_EOS: + return 1; + case TK_UNTIL: return withuntil; + default: return 0; + } +} + + +static void statlist (LexState *ls) { + /* statlist -> { stat [`;'] } */ + while (!block_follow(ls, 1)) { + if (ls->t.token == TK_RETURN) { + statement(ls); + return; /* 'return' must be last statement */ + } + statement(ls); + } +} + + +static void fieldsel (LexState *ls, expdesc *v) { + /* fieldsel -> ['.' | ':'] NAME */ FuncState *fs = ls->fs; expdesc key; - luaK_exp2anyreg(fs, v); + luaK_exp2anyregup(fs, v); luaX_next(ls); /* skip the dot or colon */ checkname(ls, &key); luaK_indexed(fs, v, &key); @@ -447,7 +656,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) { expdesc key, val; int rkkey; if (ls->t.token == TK_NAME) { - luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); checkname(ls, &key); } else /* ls->t.token == '[' */ @@ -456,7 +665,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) { checknext(ls, '='); rkkey = luaK_exp2RK(fs, &key); expr(ls, &val); - luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); fs->freereg = reg; /* free registers */ } @@ -466,7 +675,7 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) { luaK_exp2nextreg(fs, &cc->v); cc->v.k = VVOID; if (cc->tostore == LFIELDS_PER_FLUSH) { - luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ cc->tostore = 0; /* no more items pending */ } } @@ -476,27 +685,51 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) { if (cc->tostore == 0) return; if (hasmultret(cc->v.k)) { luaK_setmultret(fs, &cc->v); - luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); + luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); cc->na--; /* do not count last expression (unknown number of elements) */ } else { if (cc->v.k != VVOID) luaK_exp2nextreg(fs, &cc->v); - luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); } } static void listfield (LexState *ls, struct ConsControl *cc) { + /* listfield -> exp */ expr(ls, &cc->v); - luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); cc->na++; cc->tostore++; } +static void field (LexState *ls, struct ConsControl *cc) { + /* field -> listfield | recfield */ + switch(ls->t.token) { + case TK_NAME: { /* may be 'listfield' or 'recfield' */ + if (luaX_lookahead(ls) != '=') /* expression? */ + listfield(ls, cc); + else + recfield(ls, cc); + break; + } + case '[': { + recfield(ls, cc); + break; + } + default: { + listfield(ls, cc); + break; + } + } +} + + static void constructor (LexState *ls, expdesc *t) { - /* constructor -> ?? */ + /* constructor -> '{' [ field { sep field } [sep] ] '}' + sep -> ',' | ';' */ FuncState *fs = ls->fs; int line = ls->linenumber; int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); @@ -505,30 +738,13 @@ static void constructor (LexState *ls, expdesc *t) { cc.t = t; init_exp(t, VRELOCABLE, pc); init_exp(&cc.v, VVOID, 0); /* no value (yet) */ - luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ checknext(ls, '{'); do { lua_assert(cc.v.k == VVOID || cc.tostore > 0); if (ls->t.token == '}') break; closelistfield(fs, &cc); - switch(ls->t.token) { - case TK_NAME: { /* may be listfields or recfields */ - luaX_lookahead(ls); - if (ls->lookahead.token != '=') /* expression? */ - listfield(ls, &cc); - else - recfield(ls, &cc); - break; - } - case '[': { /* constructor_item -> recfield */ - recfield(ls, &cc); - break; - } - default: { /* constructor_part -> listfield */ - listfield(ls, &cc); - break; - } - } + field(ls, &cc); } while (testnext(ls, ',') || testnext(ls, ';')); check_match(ls, '}', '{', line); lastlistfield(fs, &cc); @@ -550,17 +766,13 @@ static void parlist (LexState *ls) { do { switch (ls->t.token) { case TK_NAME: { /* param -> NAME */ - new_localvar(ls, str_checkname(ls), nparams++); + new_localvar(ls, str_checkname(ls)); + nparams++; break; } case TK_DOTS: { /* param -> `...' */ luaX_next(ls); -#if defined(LUA_COMPAT_VARARG) - /* use `arg' as default name */ - new_localvarliteral(ls, "arg", nparams++); - f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; -#endif - f->is_vararg |= VARARG_ISVARARG; + f->is_vararg = 1; break; } default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); @@ -568,33 +780,35 @@ static void parlist (LexState *ls) { } while (!f->is_vararg && testnext(ls, ',')); } adjustlocalvars(ls, nparams); - f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); + f->numparams = cast_byte(fs->nactvar); luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ } -static void body (LexState *ls, expdesc *e, int needself, int line) { - /* body -> `(' parlist `)' chunk END */ +static void body (LexState *ls, expdesc *e, int ismethod, int line) { + /* body -> `(' parlist `)' block END */ FuncState new_fs; - open_func(ls, &new_fs); + BlockCnt bl; + new_fs.f = addprototype(ls); new_fs.f->linedefined = line; + open_func(ls, &new_fs, &bl); checknext(ls, '('); - if (needself) { - new_localvarliteral(ls, "self", 0); + if (ismethod) { + new_localvarliteral(ls, "self"); /* create 'self' parameter */ adjustlocalvars(ls, 1); } parlist(ls); checknext(ls, ')'); - chunk(ls); + statlist(ls); new_fs.f->lastlinedefined = ls->linenumber; check_match(ls, TK_END, TK_FUNCTION, line); + codeclosure(ls, e); close_func(ls); - pushclosure(ls, &new_fs, e); } -static int explist1 (LexState *ls, expdesc *v) { - /* explist1 -> expr { `,' expr } */ +static int explist (LexState *ls, expdesc *v) { + /* explist -> expr { `,' expr } */ int n = 1; /* at least one expression */ expr(ls, v); while (testnext(ls, ',')) { @@ -606,20 +820,17 @@ static int explist1 (LexState *ls, expdesc *v) { } -static void funcargs (LexState *ls, expdesc *f) { +static void funcargs (LexState *ls, expdesc *f, int line) { FuncState *fs = ls->fs; expdesc args; int base, nparams; - int line = ls->linenumber; switch (ls->t.token) { - case '(': { /* funcargs -> `(' [ explist1 ] `)' */ - if (line != ls->lastline) - luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); + case '(': { /* funcargs -> `(' [ explist ] `)' */ luaX_next(ls); if (ls->t.token == ')') /* arg list is empty? */ args.k = VVOID; else { - explist1(ls, &args); + explist(ls, &args); luaK_setmultret(fs, &args); } check_match(ls, ')', '(', line); @@ -636,11 +847,10 @@ static void funcargs (LexState *ls, expdesc *f) { } default: { luaX_syntaxerror(ls, "function arguments expected"); - return; } } lua_assert(f->k == VNONRELOC); - base = f->u.s.info; /* base register for call */ + base = f->u.info; /* base register for call */ if (hasmultret(args.k)) nparams = LUA_MULTRET; /* open call */ else { @@ -664,8 +874,8 @@ static void funcargs (LexState *ls, expdesc *f) { */ -static void prefixexp (LexState *ls, expdesc *v) { - /* prefixexp -> NAME | '(' expr ')' */ +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> NAME | '(' expr ')' */ switch (ls->t.token) { case '(': { int line = ls->linenumber; @@ -681,26 +891,26 @@ static void prefixexp (LexState *ls, expdesc *v) { } default: { luaX_syntaxerror(ls, "unexpected symbol"); - return; } } } -static void primaryexp (LexState *ls, expdesc *v) { - /* primaryexp -> - prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ +static void suffixedexp (LexState *ls, expdesc *v) { + /* suffixedexp -> + primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ FuncState *fs = ls->fs; - prefixexp(ls, v); + int line = ls->linenumber; + primaryexp(ls, v); for (;;) { switch (ls->t.token) { - case '.': { /* field */ - field(ls, v); + case '.': { /* fieldsel */ + fieldsel(ls, v); break; } case '[': { /* `[' exp1 `]' */ expdesc key; - luaK_exp2anyreg(fs, v); + luaK_exp2anyregup(fs, v); yindex(ls, &key); luaK_indexed(fs, v, &key); break; @@ -710,12 +920,12 @@ static void primaryexp (LexState *ls, expdesc *v) { luaX_next(ls); checkname(ls, &key); luaK_self(fs, v, &key); - funcargs(ls, v); + funcargs(ls, v, line); break; } case '(': case TK_STRING: case '{': { /* funcargs */ luaK_exp2nextreg(fs, v); - funcargs(ls, v); + funcargs(ls, v, line); break; } default: return; @@ -725,8 +935,8 @@ static void primaryexp (LexState *ls, expdesc *v) { static void simpleexp (LexState *ls, expdesc *v) { - /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | - constructor | FUNCTION body | primaryexp */ + /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | + constructor | FUNCTION body | suffixedexp */ switch (ls->t.token) { case TK_NUMBER: { init_exp(v, VKNUM, 0); @@ -753,7 +963,6 @@ static void simpleexp (LexState *ls, expdesc *v) { FuncState *fs = ls->fs; check_condition(ls, fs->f->is_vararg, "cannot use " LUA_QL("...") " outside a vararg function"); - fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); break; } @@ -767,7 +976,7 @@ static void simpleexp (LexState *ls, expdesc *v) { return; } default: { - primaryexp(ls, v); + suffixedexp(ls, v); return; } } @@ -811,11 +1020,11 @@ static const struct { lu_byte left; /* left priority for each binary operator */ lu_byte right; /* right priority */ } priority[] = { /* ORDER OPR */ - {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ - {10, 9}, {5, 4}, /* power and concat (right associative) */ - {3, 3}, {3, 3}, /* equality and inequality */ - {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ - {2, 2}, {1, 1} /* logical (and/or) */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */ + {10, 9}, {5, 4}, /* ^, .. (right associative) */ + {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ + {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ + {2, 2}, {1, 1} /* and, or */ }; #define UNARY_PRIORITY 8 /* priority for unary operators */ @@ -825,15 +1034,16 @@ static const struct { ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } ** where `binop' is any binary operator with a priority higher than `limit' */ -static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { +static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { BinOpr op; UnOpr uop; enterlevel(ls); uop = getunopr(ls->t.token); if (uop != OPR_NOUNOPR) { + int line = ls->linenumber; luaX_next(ls); subexpr(ls, v, UNARY_PRIORITY); - luaK_prefix(ls->fs, uop, v); + luaK_prefix(ls->fs, uop, v, line); } else simpleexp(ls, v); /* expand while operators have priorities higher than `limit' */ @@ -841,11 +1051,12 @@ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { while (op != OPR_NOBINOPR && priority[op].left > limit) { expdesc v2; BinOpr nextop; + int line = ls->linenumber; luaX_next(ls); luaK_infix(ls->fs, op, v); /* read sub-expression with higher priority */ nextop = subexpr(ls, &v2, priority[op].right); - luaK_posfix(ls->fs, op, v, &v2); + luaK_posfix(ls->fs, op, v, &v2, line); op = nextop; } leavelevel(ls); @@ -868,23 +1079,12 @@ static void expr (LexState *ls, expdesc *v) { */ -static int block_follow (int token) { - switch (token) { - case TK_ELSE: case TK_ELSEIF: case TK_END: - case TK_UNTIL: case TK_EOS: - return 1; - default: return 0; - } -} - - static void block (LexState *ls) { - /* block -> chunk */ + /* block -> statlist */ FuncState *fs = ls->fs; BlockCnt bl; enterblock(fs, &bl, 0); - chunk(ls); - lua_assert(bl.breaklist == NO_JUMP); + statlist(ls); leaveblock(fs); } @@ -900,29 +1100,34 @@ struct LHS_assign { /* -** check whether, in an assignment to a local variable, the local variable -** is needed in a previous assignment (to a table). If so, save original -** local value in a safe place and use this safe copy in the previous -** assignment. +** check whether, in an assignment to an upvalue/local variable, the +** upvalue/local variable is begin used in a previous assignment to a +** table. If so, save original upvalue/local value in a safe place and +** use this safe copy in the previous assignment. */ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { FuncState *fs = ls->fs; int extra = fs->freereg; /* eventual position to save local variable */ int conflict = 0; - for (; lh; lh = lh->prev) { - if (lh->v.k == VINDEXED) { - if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ + for (; lh; lh = lh->prev) { /* check all previous assignments */ + if (lh->v.k == VINDEXED) { /* assigning to a table? */ + /* table is the upvalue/local being assigned now? */ + if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { conflict = 1; - lh->v.u.s.info = extra; /* previous assignment will use safe copy */ + lh->v.u.ind.vt = VLOCAL; + lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ } - if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ + /* index is the local being assigned? (index cannot be upvalue) */ + if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { conflict = 1; - lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ + lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ } } } if (conflict) { - luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ + /* copy upvalue/local value to a temporary (in position 'extra') */ + OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, op, extra, v->u.info, 0); luaK_reserveregs(fs, 1); } } @@ -930,22 +1135,21 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { expdesc e; - check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, - "syntax error"); - if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ + check_condition(ls, vkisvar(lh->v.k), "syntax error"); + if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ struct LHS_assign nv; nv.prev = lh; - primaryexp(ls, &nv.v); - if (nv.v.k == VLOCAL) + suffixedexp(ls, &nv.v); + if (nv.v.k != VINDEXED) check_conflict(ls, lh, &nv.v); - luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, - "variables in assignment"); + checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, + "C levels"); assignment(ls, &nv, nvars+1); } - else { /* assignment -> `=' explist1 */ + else { /* assignment -> `=' explist */ int nexps; checknext(ls, '='); - nexps = explist1(ls, &e); + nexps = explist(ls, &e); if (nexps != nvars) { adjust_assign(ls, nvars, nexps, &e); if (nexps > nvars) @@ -972,19 +1176,57 @@ static int cond (LexState *ls) { } -static void breakstat (LexState *ls) { - FuncState *fs = ls->fs; - BlockCnt *bl = fs->bl; - int upval = 0; - while (bl && !bl->isbreakable) { - upval |= bl->upval; - bl = bl->previous; +static void gotostat (LexState *ls, int pc) { + int line = ls->linenumber; + TString *label; + int g; + if (testnext(ls, TK_GOTO)) + label = str_checkname(ls); + else { + luaX_next(ls); /* skip break */ + label = luaS_new(ls->L, "break"); } - if (!bl) - luaX_syntaxerror(ls, "no loop to break"); - if (upval) - luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); - luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); + g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); + findlabel(ls, g); /* close it if label already defined */ +} + + +/* check for repeated labels on the same block */ +static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { + int i; + for (i = fs->bl->firstlabel; i < ll->n; i++) { + if (luaS_eqstr(label, ll->arr[i].name)) { + const char *msg = luaO_pushfstring(fs->ls->L, + "label " LUA_QS " already defined on line %d", + getstr(label), ll->arr[i].line); + semerror(fs->ls, msg); + } + } +} + + +/* skip no-op statements */ +static void skipnoopstat (LexState *ls) { + while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) + statement(ls); +} + + +static void labelstat (LexState *ls, TString *label, int line) { + /* label -> '::' NAME '::' */ + FuncState *fs = ls->fs; + Labellist *ll = &ls->dyd->label; + int l; /* index of new label being created */ + checkrepeated(fs, ll, label); /* check for repeated labels */ + checknext(ls, TK_DBCOLON); /* skip double colon */ + /* create new entry for this label */ + l = newlabelentry(ls, ll, label, line, fs->pc); + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ + /* assume that locals are already out of scope */ + ll->arr[l].nactvar = fs->bl->nactvar; + } + findgotos(ls, &ll->arr[l]); } @@ -1000,7 +1242,7 @@ static void whilestat (LexState *ls, int line) { enterblock(fs, &bl, 1); checknext(ls, TK_DO); block(ls); - luaK_patchlist(fs, luaK_jump(fs), whileinit); + luaK_jumpto(fs, whileinit); check_match(ls, TK_END, TK_WHILE, line); leaveblock(fs); luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ @@ -1016,30 +1258,25 @@ static void repeatstat (LexState *ls, int line) { enterblock(fs, &bl1, 1); /* loop block */ enterblock(fs, &bl2, 0); /* scope block */ luaX_next(ls); /* skip REPEAT */ - chunk(ls); + statlist(ls); check_match(ls, TK_UNTIL, TK_REPEAT, line); condexit = cond(ls); /* read condition (inside scope block) */ - if (!bl2.upval) { /* no upvalues? */ - leaveblock(fs); /* finish scope */ - luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ - } - else { /* complete semantics when there are upvalues */ - breakstat(ls); /* if condition then break */ - luaK_patchtohere(ls->fs, condexit); /* else... */ - leaveblock(fs); /* finish scope... */ - luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ - } + if (bl2.upval) /* upvalues? */ + luaK_patchclose(fs, condexit, bl2.nactvar); + leaveblock(fs); /* finish scope */ + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ leaveblock(fs); /* finish loop */ } static int exp1 (LexState *ls) { expdesc e; - int k; + int reg; expr(ls, &e); - k = e.k; luaK_exp2nextreg(ls->fs, &e); - return k; + lua_assert(e.k == VNONRELOC); + reg = e.u.info; + return reg; } @@ -1057,10 +1294,15 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { block(ls); leaveblock(fs); /* end of scope for declared variables */ luaK_patchtohere(fs, prep); - endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : - luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); - luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ - luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); + if (isnum) /* numeric for? */ + endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); + else { /* generic for */ + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); + } + luaK_patchlist(fs, endfor, prep + 1); + luaK_fixline(fs, line); } @@ -1068,10 +1310,10 @@ static void fornum (LexState *ls, TString *varname, int line) { /* fornum -> NAME = exp1,exp1[,exp1] forbody */ FuncState *fs = ls->fs; int base = fs->freereg; - new_localvarliteral(ls, "(for index)", 0); - new_localvarliteral(ls, "(for limit)", 1); - new_localvarliteral(ls, "(for step)", 2); - new_localvar(ls, varname, 3); + new_localvarliteral(ls, "(for index)"); + new_localvarliteral(ls, "(for limit)"); + new_localvarliteral(ls, "(for step)"); + new_localvar(ls, varname); checknext(ls, '='); exp1(ls); /* initial value */ checknext(ls, ','); @@ -1079,7 +1321,7 @@ static void fornum (LexState *ls, TString *varname, int line) { if (testnext(ls, ',')) exp1(ls); /* optional step */ else { /* default step = 1 */ - luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1)); luaK_reserveregs(fs, 1); } forbody(ls, base, line, 1, 1); @@ -1087,23 +1329,25 @@ static void fornum (LexState *ls, TString *varname, int line) { static void forlist (LexState *ls, TString *indexname) { - /* forlist -> NAME {,NAME} IN explist1 forbody */ + /* forlist -> NAME {,NAME} IN explist forbody */ FuncState *fs = ls->fs; expdesc e; - int nvars = 0; + int nvars = 4; /* gen, state, control, plus at least one declared var */ int line; int base = fs->freereg; /* create control variables */ - new_localvarliteral(ls, "(for generator)", nvars++); - new_localvarliteral(ls, "(for state)", nvars++); - new_localvarliteral(ls, "(for control)", nvars++); + new_localvarliteral(ls, "(for generator)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for control)"); /* create declared variables */ - new_localvar(ls, indexname, nvars++); - while (testnext(ls, ',')) - new_localvar(ls, str_checkname(ls), nvars++); + new_localvar(ls, indexname); + while (testnext(ls, ',')) { + new_localvar(ls, str_checkname(ls)); + nvars++; + } checknext(ls, TK_IN); line = ls->linenumber; - adjust_assign(ls, 3, explist1(ls, &e), &e); + adjust_assign(ls, 3, explist(ls, &e), &e); luaK_checkstack(fs, 3); /* extra space to call generator */ forbody(ls, base, line, nvars - 3, 0); } @@ -1127,65 +1371,77 @@ static void forstat (LexState *ls, int line) { } -static int test_then_block (LexState *ls) { +static void test_then_block (LexState *ls, int *escapelist) { /* test_then_block -> [IF | ELSEIF] cond THEN block */ - int condexit; + BlockCnt bl; + FuncState *fs = ls->fs; + expdesc v; + int jf; /* instruction to skip 'then' code (if condition is false) */ luaX_next(ls); /* skip IF or ELSEIF */ - condexit = cond(ls); + expr(ls, &v); /* read condition */ checknext(ls, TK_THEN); - block(ls); /* `then' part */ - return condexit; + if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { + luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ + enterblock(fs, &bl, 0); /* must enter block before 'goto' */ + gotostat(ls, v.t); /* handle goto/break */ + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ + leaveblock(fs); + return; /* and that is it */ + } + else /* must skip over 'then' part if condition is false */ + jf = luaK_jump(fs); + } + else { /* regular case (not goto/break) */ + luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ + enterblock(fs, &bl, 0); + jf = v.f; + } + statlist(ls); /* `then' part */ + leaveblock(fs); + if (ls->t.token == TK_ELSE || + ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ + luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); } static void ifstat (LexState *ls, int line) { /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ FuncState *fs = ls->fs; - int flist; - int escapelist = NO_JUMP; - flist = test_then_block(ls); /* IF cond THEN block */ - while (ls->t.token == TK_ELSEIF) { - luaK_concat(fs, &escapelist, luaK_jump(fs)); - luaK_patchtohere(fs, flist); - flist = test_then_block(ls); /* ELSEIF cond THEN block */ - } - if (ls->t.token == TK_ELSE) { - luaK_concat(fs, &escapelist, luaK_jump(fs)); - luaK_patchtohere(fs, flist); - luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ + int escapelist = NO_JUMP; /* exit list for finished parts */ + test_then_block(ls, &escapelist); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ + if (testnext(ls, TK_ELSE)) block(ls); /* `else' part */ - } - else - luaK_concat(fs, &escapelist, flist); - luaK_patchtohere(fs, escapelist); check_match(ls, TK_END, TK_IF, line); + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ } static void localfunc (LexState *ls) { - expdesc v, b; + expdesc b; FuncState *fs = ls->fs; - new_localvar(ls, str_checkname(ls), 0); - init_exp(&v, VLOCAL, fs->freereg); - luaK_reserveregs(fs, 1); - adjustlocalvars(ls, 1); - body(ls, &b, 0, ls->linenumber); - luaK_storevar(fs, &v, &b); + new_localvar(ls, str_checkname(ls)); /* new local variable */ + adjustlocalvars(ls, 1); /* enter its scope */ + body(ls, &b, 0, ls->linenumber); /* function created in next register */ /* debug information will only see the variable after this point! */ - getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; + getlocvar(fs, b.u.info)->startpc = fs->pc; } static void localstat (LexState *ls) { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ int nvars = 0; int nexps; expdesc e; do { - new_localvar(ls, str_checkname(ls), nvars++); + new_localvar(ls, str_checkname(ls)); + nvars++; } while (testnext(ls, ',')); if (testnext(ls, '=')) - nexps = explist1(ls, &e); + nexps = explist(ls, &e); else { e.k = VVOID; nexps = 0; @@ -1196,26 +1452,26 @@ static void localstat (LexState *ls) { static int funcname (LexState *ls, expdesc *v) { - /* funcname -> NAME {field} [`:' NAME] */ - int needself = 0; + /* funcname -> NAME {fieldsel} [`:' NAME] */ + int ismethod = 0; singlevar(ls, v); while (ls->t.token == '.') - field(ls, v); + fieldsel(ls, v); if (ls->t.token == ':') { - needself = 1; - field(ls, v); + ismethod = 1; + fieldsel(ls, v); } - return needself; + return ismethod; } static void funcstat (LexState *ls, int line) { /* funcstat -> FUNCTION funcname body */ - int needself; + int ismethod; expdesc v, b; luaX_next(ls); /* skip FUNCTION */ - needself = funcname(ls, &v); - body(ls, &b, needself, line); + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); luaK_storevar(ls->fs, &v, &b); luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ } @@ -1225,26 +1481,27 @@ static void exprstat (LexState *ls) { /* stat -> func | assignment */ FuncState *fs = ls->fs; struct LHS_assign v; - primaryexp(ls, &v.v); - if (v.v.k == VCALL) /* stat -> func */ - SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ - else { /* stat -> assignment */ + suffixedexp(ls, &v.v); + if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ v.prev = NULL; assignment(ls, &v, 1); } + else { /* stat -> func */ + check_condition(ls, v.v.k == VCALL, "syntax error"); + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + } } static void retstat (LexState *ls) { - /* stat -> RETURN explist */ + /* stat -> RETURN [explist] [';'] */ FuncState *fs = ls->fs; expdesc e; int first, nret; /* registers with returned values */ - luaX_next(ls); /* skip RETURN */ - if (block_follow(ls->t.token) || ls->t.token == ';') + if (block_follow(ls, 1) || ls->t.token == ';') first = nret = 0; /* return no values */ else { - nret = explist1(ls, &e); /* optional return values */ + nret = explist(ls, &e); /* optional return values */ if (hasmultret(e.k)) { luaK_setmultret(fs, &e); if (e.k == VCALL && nret == 1) { /* tail call? */ @@ -1265,37 +1522,43 @@ static void retstat (LexState *ls) { } } luaK_ret(fs, first, nret); + testnext(ls, ';'); /* skip optional semicolon */ } -static int statement (LexState *ls) { +static void statement (LexState *ls) { int line = ls->linenumber; /* may be needed for error messages */ + enterlevel(ls); switch (ls->t.token) { + case ';': { /* stat -> ';' (empty statement) */ + luaX_next(ls); /* skip ';' */ + break; + } case TK_IF: { /* stat -> ifstat */ ifstat(ls, line); - return 0; + break; } case TK_WHILE: { /* stat -> whilestat */ whilestat(ls, line); - return 0; + break; } case TK_DO: { /* stat -> DO block END */ luaX_next(ls); /* skip DO */ block(ls); check_match(ls, TK_END, TK_DO, line); - return 0; + break; } case TK_FOR: { /* stat -> forstat */ forstat(ls, line); - return 0; + break; } case TK_REPEAT: { /* stat -> repeatstat */ repeatstat(ls, line); - return 0; + break; } - case TK_FUNCTION: { - funcstat(ls, line); /* stat -> funcstat */ - return 0; + case TK_FUNCTION: { /* stat -> funcstat */ + funcstat(ls, line); + break; } case TK_LOCAL: { /* stat -> localstat */ luaX_next(ls); /* skip LOCAL */ @@ -1303,37 +1566,73 @@ static int statement (LexState *ls) { localfunc(ls); else localstat(ls); - return 0; + break; + } + case TK_DBCOLON: { /* stat -> label */ + luaX_next(ls); /* skip double colon */ + labelstat(ls, str_checkname(ls), line); + break; } case TK_RETURN: { /* stat -> retstat */ + luaX_next(ls); /* skip RETURN */ retstat(ls); - return 1; /* must be last statement */ + break; } - case TK_BREAK: { /* stat -> breakstat */ - luaX_next(ls); /* skip BREAK */ - breakstat(ls); - return 1; /* must be last statement */ + case TK_BREAK: /* stat -> breakstat */ + case TK_GOTO: { /* stat -> 'goto' NAME */ + gotostat(ls, luaK_jump(ls->fs)); + break; } - default: { + default: { /* stat -> func | assignment */ exprstat(ls); - return 0; /* to avoid warnings */ + break; } } -} - - -static void chunk (LexState *ls) { - /* chunk -> { stat [`;'] } */ - int islast = 0; - enterlevel(ls); - while (!islast && !block_follow(ls->t.token)) { - islast = statement(ls); - testnext(ls, ';'); - lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && - ls->fs->freereg >= ls->fs->nactvar); - ls->fs->freereg = ls->fs->nactvar; /* free registers */ - } + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ leavelevel(ls); } /* }====================================================================== */ + + +/* +** compiles the main function, which is a regular vararg function with an +** upvalue named LUA_ENV +*/ +static void mainfunc (LexState *ls, FuncState *fs) { + BlockCnt bl; + expdesc v; + open_func(ls, fs, &bl); + fs->f->is_vararg = 1; /* main function is always vararg */ + init_exp(&v, VLOCAL, 0); /* create and... */ + newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaX_next(ls); /* read first token */ + statlist(ls); /* parse main body */ + check(ls, TK_EOS); + close_func(ls); +} + + +Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar) { + LexState lexstate; + FuncState funcstate; + Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ + /* anchor closure (to avoid being collected) */ + setclLvalue(L, L->top, cl); + incr_top(L); + funcstate.f = cl->l.p = luaF_newproto(L); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ + lexstate.buff = buff; + lexstate.dyd = dyd; + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); + mainfunc(&lexstate, &funcstate); + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); + /* all scopes should be correctly finished */ + lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); + return cl; /* it's on the stack too */ +} + diff --git a/src/mod/languages/mod_lua/lua/lparser.h b/src/mod/languages/mod_lua/lua/lparser.h index 18836afd1c..301167d4f5 100644 --- a/src/mod/languages/mod_lua/lua/lparser.h +++ b/src/mod/languages/mod_lua/lua/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lparser.h,v 1.70 2012/05/08 13:53:33 roberto Exp $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -23,34 +23,72 @@ typedef enum { VFALSE, VK, /* info = index of constant in `k' */ VKNUM, /* nval = numerical value */ + VNONRELOC, /* info = result register */ VLOCAL, /* info = local register */ - VUPVAL, /* info = index of upvalue in `upvalues' */ - VGLOBAL, /* info = index of table; aux = index of global name in `k' */ - VINDEXED, /* info = table register; aux = index register (or `k') */ + VUPVAL, /* info = index of upvalue in 'upvalues' */ + VINDEXED, /* t = table register/upvalue; idx = index R/K */ VJMP, /* info = instruction pc */ VRELOCABLE, /* info = instruction pc */ - VNONRELOC, /* info = result register */ VCALL, /* info = instruction pc */ VVARARG /* info = instruction pc */ } expkind; + +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) +#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) + typedef struct expdesc { expkind k; union { - struct { int info, aux; } s; - lua_Number nval; + struct { /* for indexed variables (VINDEXED) */ + short idx; /* index (R/K) */ + lu_byte t; /* table (register or upvalue) */ + lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ + } ind; + int info; /* for generic use */ + lua_Number nval; /* for VKNUM */ } u; int t; /* patch list of `exit when true' */ int f; /* patch list of `exit when false' */ } expdesc; -typedef struct upvaldesc { - lu_byte k; - lu_byte info; -} upvaldesc; +/* description of active local variable */ +typedef struct Vardesc { + short idx; /* variable index in stack */ +} Vardesc; +/* description of pending goto statements and label statements */ +typedef struct Labeldesc { + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* local level where it appears in current block */ +} Labeldesc; + + +/* list of labels or gotos */ +typedef struct Labellist { + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ +} Labellist; + + +/* dynamic structures used by the parser */ +typedef struct Dyndata { + struct { /* list of active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ +} Dyndata; + + +/* control of blocks */ struct BlockCnt; /* defined in lparser.c */ @@ -60,23 +98,22 @@ typedef struct FuncState { Table *h; /* table to find (and reuse) elements in `k' */ struct FuncState *prev; /* enclosing function */ struct LexState *ls; /* lexical state */ - struct lua_State *L; /* copy of the Lua state */ struct BlockCnt *bl; /* chain of current blocks */ int pc; /* next position to code (equivalent to `ncode') */ - int lasttarget; /* `pc' of last `jump target' */ + int lasttarget; /* 'label' of last 'jump label' */ int jpc; /* list of pending jumps to `pc' */ - int freereg; /* first free register */ int nk; /* number of elements in `k' */ int np; /* number of elements in `p' */ - short nlocvars; /* number of elements in `locvars' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + short nlocvars; /* number of elements in 'f->locvars' */ lu_byte nactvar; /* number of active local variables */ - upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ - unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ } FuncState; -LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, - const char *name); +LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); #endif diff --git a/src/mod/languages/mod_lua/lua/lstate.c b/src/mod/languages/mod_lua/lua/lstate.c index 4313b83a0c..207a106d5b 100644 --- a/src/mod/languages/mod_lua/lua/lstate.c +++ b/src/mod/languages/mod_lua/lua/lstate.c @@ -1,17 +1,19 @@ /* -** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ +** $Id: lstate.c,v 2.99 2012/10/02 17:40:53 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ #include +#include #define lstate_c #define LUA_CORE #include "lua.h" +#include "lapi.h" #include "ldebug.h" #include "ldo.h" #include "lfunc.h" @@ -24,119 +26,236 @@ #include "ltm.h" -#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) -#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) -#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) +#if !defined(LUAI_GCPAUSE) +#define LUAI_GCPAUSE 200 /* 200% */ +#endif + +#if !defined(LUAI_GCMAJOR) +#define LUAI_GCMAJOR 200 /* 200% */ +#endif + +#if !defined(LUAI_GCMUL) +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ +#endif + + +#define MEMERRMSG "not enough memory" + + +/* +** a macro to help the creation of a unique random seed when a state is +** created; the seed is used to randomize hashes. +*/ +#if !defined(luai_makeseed) +#include +#define luai_makeseed() cast(unsigned int, time(NULL)) +#endif + + + +/* +** thread state + extra space +*/ +typedef struct LX { +#if defined(LUAI_EXTRASPACE) + char buff[LUAI_EXTRASPACE]; +#endif + lua_State l; +} LX; /* ** Main thread combines a thread state and the global state */ typedef struct LG { - lua_State l; + LX l; global_State g; } LG; - -static void stack_init (lua_State *L1, lua_State *L) { - /* initialize CallInfo array */ - L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); - L1->ci = L1->base_ci; - L1->size_ci = BASIC_CI_SIZE; - L1->end_ci = L1->base_ci + L1->size_ci - 1; - /* initialize stack array */ - L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); - L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; - L1->top = L1->stack; - L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; - /* initialize first ci */ - L1->ci->func = L1->top; - setnilvalue(L1->top++); /* `function' entry for this `ci' */ - L1->base = L1->ci->base = L1->top; - L1->ci->top = L1->top + LUA_MINSTACK; -} + +#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) -static void freestack (lua_State *L, lua_State *L1) { - luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); - luaM_freearray(L, L1->stack, L1->stacksize, TValue); +/* +** Compute an initial seed as random as possible. In ANSI, rely on +** Address Space Layout Randomization (if present) to increase +** randomness.. +*/ +#define addbuff(b,p,e) \ + { size_t t = cast(size_t, e); \ + memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } + +static unsigned int makeseed (lua_State *L) { + char buff[4 * sizeof(size_t)]; + unsigned int h = luai_makeseed(); + int p = 0; + addbuff(buff, p, L); /* heap variable */ + addbuff(buff, p, &h); /* local variable */ + addbuff(buff, p, luaO_nilobject); /* global variable */ + addbuff(buff, p, &lua_newstate); /* public function */ + lua_assert(p == sizeof(buff)); + return luaS_hash(buff, p, h); } /* -** open parts that may cause memory-allocation errors +** set GCdebt to a new value keeping the value (totalbytes + GCdebt) +** invariant +*/ +void luaE_setdebt (global_State *g, l_mem debt) { + g->totalbytes -= (debt - g->GCdebt); + g->GCdebt = debt; +} + + +CallInfo *luaE_extendCI (lua_State *L) { + CallInfo *ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); + L->ci->next = ci; + ci->previous = L->ci; + ci->next = NULL; + return ci; +} + + +void luaE_freeCI (lua_State *L) { + CallInfo *ci = L->ci; + CallInfo *next = ci->next; + ci->next = NULL; + while ((ci = next) != NULL) { + next = ci->next; + luaM_free(L, ci); + } +} + + +static void stack_init (lua_State *L1, lua_State *L) { + int i; CallInfo *ci; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); + L1->stacksize = BASIC_STACK_SIZE; + for (i = 0; i < BASIC_STACK_SIZE; i++) + setnilvalue(L1->stack + i); /* erase new stack */ + L1->top = L1->stack; + L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; + /* initialize first ci */ + ci = &L1->base_ci; + ci->next = ci->previous = NULL; + ci->callstatus = 0; + ci->func = L1->top; + setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ + ci->top = L1->top + LUA_MINSTACK; + L1->ci = ci; +} + + +static void freestack (lua_State *L) { + if (L->stack == NULL) + return; /* stack not completely built yet */ + L->ci = &L->base_ci; /* free the entire 'ci' list */ + luaE_freeCI(L); + luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ +} + + +/* +** Create registry table and its predefined values +*/ +static void init_registry (lua_State *L, global_State *g) { + TValue mt; + /* create registry */ + Table *registry = luaH_new(L); + sethvalue(L, &g->l_registry, registry); + luaH_resize(L, registry, LUA_RIDX_LAST, 0); + /* registry[LUA_RIDX_MAINTHREAD] = L */ + setthvalue(L, &mt, L); + luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); + /* registry[LUA_RIDX_GLOBALS] = table of globals */ + sethvalue(L, &mt, luaH_new(L)); + luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); +} + + +/* +** open parts of the state that may cause memory-allocation errors */ static void f_luaopen (lua_State *L, void *ud) { global_State *g = G(L); UNUSED(ud); stack_init(L, L); /* init stack */ - sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ - sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ + init_registry(L, g); luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ luaT_init(L); luaX_init(L); - luaS_fix(luaS_newliteral(L, MEMERRMSG)); - g->GCthreshold = 4*g->totalbytes; + /* pre-create memory-error message */ + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); + luaS_fix(g->memerrmsg); /* it should never be collected */ + g->gcrunning = 1; /* allow gc */ } +/* +** preinitialize a state with consistent values without allocating +** any memory (to avoid errors) +*/ static void preinit_state (lua_State *L, global_State *g) { G(L) = g; L->stack = NULL; + L->ci = NULL; L->stacksize = 0; L->errorJmp = NULL; + L->nCcalls = 0; L->hook = NULL; L->hookmask = 0; L->basehookcount = 0; L->allowhook = 1; resethookcount(L); L->openupval = NULL; - L->size_ci = 0; - L->nCcalls = L->baseCcalls = 0; - L->status = 0; - L->base_ci = L->ci = NULL; - L->savedpc = NULL; + L->nny = 1; + L->status = LUA_OK; L->errfunc = 0; - setnilvalue(gt(L)); } static void close_state (lua_State *L) { global_State *g = G(L); luaF_close(L, L->stack); /* close all upvalues for this thread */ - luaC_freeall(L); /* collect all objects */ - lua_assert(g->rootgc == obj2gco(L)); - lua_assert(g->strt.nuse == 0); - luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); + luaC_freeallobjects(L); /* collect all objects */ + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); luaZ_freebuffer(L, &g->buff); - freestack(L, L); - lua_assert(g->totalbytes == sizeof(LG)); - (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); + freestack(L); + lua_assert(gettotalbytes(g) == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ } -lua_State *luaE_newthread (lua_State *L) { - lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); - luaC_link(L, obj2gco(L1), LUA_TTHREAD); +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; + setthvalue(L, L->top, L1); + api_incr_top(L); preinit_state(L1, G(L)); - stack_init(L1, L); /* init stack */ - setobj2n(L, gt(L1), gt(L)); /* share table of globals */ L1->hookmask = L->hookmask; L1->basehookcount = L->basehookcount; L1->hook = L->hook; resethookcount(L1); - lua_assert(iswhite(obj2gco(L1))); + luai_userstatethread(L, L1); + stack_init(L1, L); /* init stack */ + lua_unlock(L); return L1; } void luaE_freethread (lua_State *L, lua_State *L1) { + LX *l = fromstate(L1); luaF_close(L1, L1->stack); /* close all upvalues for this thread */ lua_assert(L1->openupval == NULL); - luai_userstatefree(L1); - freestack(L, L1); - luaM_freemem(L, fromstate(L1), state_size(lua_State)); + luai_userstatefree(L, L1); + freestack(L1); + luaM_free(L, l); } @@ -144,42 +263,45 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { int i; lua_State *L; global_State *g; - void *l = (*f)(ud, NULL, 0, state_size(LG)); + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); if (l == NULL) return NULL; - L = tostate(l); - g = &((LG *)L)->g; + L = &l->l.l; + g = &l->g; L->next = NULL; L->tt = LUA_TTHREAD; g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); L->marked = luaC_white(g); - set2bits(L->marked, FIXEDBIT, SFIXEDBIT); + g->gckind = KGC_NORMAL; preinit_state(L, g); g->frealloc = f; g->ud = ud; g->mainthread = L; + g->seed = makeseed(L); g->uvhead.u.l.prev = &g->uvhead; g->uvhead.u.l.next = &g->uvhead; - g->GCthreshold = 0; /* mark it as unfinished state */ + g->gcrunning = 0; /* no GC while building state */ + g->GCestimate = 0; g->strt.size = 0; g->strt.nuse = 0; g->strt.hash = NULL; - setnilvalue(registry(L)); + setnilvalue(&g->l_registry); luaZ_initbuffer(L, &g->buff); g->panic = NULL; + g->version = lua_version(NULL); g->gcstate = GCSpause; - g->rootgc = obj2gco(L); - g->sweepstrgc = 0; - g->sweepgc = &g->rootgc; - g->gray = NULL; - g->grayagain = NULL; - g->weak = NULL; - g->tmudata = NULL; + g->allgc = NULL; + g->finobj = NULL; + g->tobefnz = NULL; + g->sweepgc = g->sweepfin = NULL; + g->gray = g->grayagain = NULL; + g->weak = g->ephemeron = g->allweak = NULL; g->totalbytes = sizeof(LG); + g->GCdebt = 0; g->gcpause = LUAI_GCPAUSE; + g->gcmajorinc = LUAI_GCMAJOR; g->gcstepmul = LUAI_GCMUL; - g->gcdept = 0; - for (i=0; imt[i] = NULL; - if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { + for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { /* memory allocation error: free partial state */ close_state(L); L = NULL; @@ -190,25 +312,11 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { } -static void callallgcTM (lua_State *L, void *ud) { - UNUSED(ud); - luaC_callGCTM(L); /* call GC metamethods for all udata */ -} - - LUA_API void lua_close (lua_State *L) { L = G(L)->mainthread; /* only the main thread can be closed */ lua_lock(L); - luaF_close(L, L->stack); /* close all upvalues for this thread */ - luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ - L->errfunc = 0; /* no error function during GC metamethods */ - do { /* repeat until no more errors */ - L->ci = L->base_ci; - L->base = L->top = L->ci->base; - L->nCcalls = L->baseCcalls = 0; - } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); - lua_assert(G(L)->tmudata == NULL); luai_userstateclose(L); close_state(L); } + diff --git a/src/mod/languages/mod_lua/lua/lstate.h b/src/mod/languages/mod_lua/lua/lstate.h index 3bc575b6bc..c8a31f5c0b 100644 --- a/src/mod/languages/mod_lua/lua/lstate.h +++ b/src/mod/languages/mod_lua/lua/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ +** $Id: lstate.h,v 2.82 2012/07/02 13:37:04 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -14,26 +14,47 @@ #include "lzio.h" +/* + +** Some notes about garbage-collected objects: All objects in Lua must +** be kept somehow accessible until being freed. +** +** Lua keeps most objects linked in list g->allgc. The link uses field +** 'next' of the CommonHeader. +** +** Strings are kept in several lists headed by the array g->strt.hash. +** +** Open upvalues are not subject to independent garbage collection. They +** are collected together with their respective threads. Lua keeps a +** double-linked list with all open upvalues (g->uvhead) so that it can +** mark objects referred by them. (They are always gray, so they must +** be remarked in the atomic step. Usually their contents would be marked +** when traversing the respective threads, but the thread may already be +** dead, while the upvalue is still accessible through closures.) +** +** Objects with finalizers are kept in the list g->finobj. +** +** The list g->tobefnz links all objects being finalized. + +*/ + struct lua_longjmp; /* defined in ldo.c */ -/* table of globals */ -#define gt(L) (&L->l_gt) - -/* registry */ -#define registry(L) (&G(L)->l_registry) - /* extra stack space to handle TM calls and some other extras */ #define EXTRA_STACK 5 -#define BASIC_CI_SIZE 8 - #define BASIC_STACK_SIZE (2*LUA_MINSTACK) +/* kinds of Garbage Collection */ +#define KGC_NORMAL 0 +#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ +#define KGC_GEN 2 /* generational collection */ + typedef struct stringtable { GCObject **hash; @@ -43,54 +64,87 @@ typedef struct stringtable { /* -** informations about a call +** information about a call */ typedef struct CallInfo { - StkId base; /* base for this function */ StkId func; /* function index in the stack */ StkId top; /* top for this function */ - const Instruction *savedpc; - int nresults; /* expected number of results from this function */ - int tailcalls; /* number of tail calls lost under this entry */ + struct CallInfo *previous, *next; /* dynamic call link */ + short nresults; /* expected number of results from this function */ + lu_byte callstatus; + ptrdiff_t extra; + union { + struct { /* only for Lua functions */ + StkId base; /* base for this function */ + const Instruction *savedpc; + } l; + struct { /* only for C functions */ + int ctx; /* context info. in case of yields */ + lua_CFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lu_byte old_allowhook; + lu_byte status; + } c; + } u; } CallInfo; +/* +** Bits in CallInfo status +*/ +#define CIST_LUA (1<<0) /* call is running a Lua function */ +#define CIST_HOOKED (1<<1) /* call is running a debug hook */ +#define CIST_REENTRY (1<<2) /* call is running on same invocation of + luaV_execute of previous call */ +#define CIST_YIELDED (1<<3) /* call reentered after suspension */ +#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ +#define CIST_STAT (1<<5) /* call has an error status (pcall) */ +#define CIST_TAIL (1<<6) /* call was tail called */ +#define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ -#define curr_func(L) (clvalue(L->ci->func)) -#define ci_func(ci) (clvalue((ci)->func)) -#define f_isLua(ci) (!ci_func(ci)->c.isC) -#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) + +#define isLua(ci) ((ci)->callstatus & CIST_LUA) /* ** `global state', shared by all threads of this state */ typedef struct global_State { - stringtable strt; /* hash table for strings */ lua_Alloc frealloc; /* function to reallocate memory */ void *ud; /* auxiliary data to `frealloc' */ + lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCmemtrav; /* memory traversed by the GC */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + unsigned int seed; /* randomized seed for hashes */ lu_byte currentwhite; lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcrunning; /* true if GC is running */ int sweepstrgc; /* position of sweep in `strt' */ - GCObject *rootgc; /* list of all collectable objects */ - GCObject **sweepgc; /* position of sweep in `rootgc' */ + GCObject *allgc; /* list of all collectable objects */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject **sweepgc; /* current position of sweep in list 'allgc' */ + GCObject **sweepfin; /* current position of sweep in list 'finobj' */ GCObject *gray; /* list of gray objects */ GCObject *grayagain; /* list of objects to be traversed atomically */ - GCObject *weak; /* list of weak tables (to be cleared) */ - GCObject *tmudata; /* last element of list of userdata to be GC */ - Mbuffer buff; /* temporary buffer for string concatentation */ - lu_mem GCthreshold; - lu_mem totalbytes; /* number of bytes currently allocated */ - lu_mem estimate; /* an estimate of number of bytes actually in use */ - lu_mem gcdept; /* how much GC is `behind schedule' */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + UpVal uvhead; /* head of double-linked list of all open upvalues */ + Mbuffer buff; /* temporary buffer for string concatenation */ int gcpause; /* size of pause between successive GCs */ + int gcmajorinc; /* pause between major collections (only in gen. mode) */ int gcstepmul; /* GC `granularity' */ lua_CFunction panic; /* to be called in unprotected errors */ - TValue l_registry; struct lua_State *mainthread; - UpVal uvhead; /* head of double-linked list of all open upvalues */ - struct Table *mt[NUM_TAGS]; /* metatables for basic types */ + const lua_Number *version; /* pointer to version number */ + TString *memerrmsg; /* memory-error message */ TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ } global_State; @@ -101,29 +155,24 @@ struct lua_State { CommonHeader; lu_byte status; StkId top; /* first free slot in the stack */ - StkId base; /* base of current function */ global_State *l_G; CallInfo *ci; /* call info for current function */ - const Instruction *savedpc; /* `savedpc' of current function */ + const Instruction *oldpc; /* last pc traced */ StkId stack_last; /* last free slot in the stack */ StkId stack; /* stack base */ - CallInfo *end_ci; /* points after end of ci array*/ - CallInfo *base_ci; /* array of CallInfo's */ int stacksize; - int size_ci; /* size of array `base_ci' */ + unsigned short nny; /* number of non-yieldable calls in stack */ unsigned short nCcalls; /* number of nested C calls */ - unsigned short baseCcalls; /* nested C calls when resuming coroutine */ lu_byte hookmask; lu_byte allowhook; int basehookcount; int hookcount; lua_Hook hook; - TValue l_gt; /* table of globals */ - TValue env; /* temporary place for environments */ GCObject *openupval; /* list of open upvalues in this stack */ GCObject *gclist; struct lua_longjmp *errorJmp; /* current error recover point */ ptrdiff_t errfunc; /* current error handling function (stack index) */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ }; @@ -134,7 +183,7 @@ struct lua_State { ** Union of all collectable objects */ union GCObject { - GCheader gch; + GCheader gch; /* common header */ union TString ts; union Udata u; union Closure cl; @@ -145,25 +194,35 @@ union GCObject { }; +#define gch(o) (&(o)->gch) + /* macros to convert a GCObject into a specific value */ -#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define rawgco2ts(o) \ + check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts)) #define gco2ts(o) (&rawgco2ts(o)->tsv) #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) #define gco2u(o) (&rawgco2u(o)->uv) -#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) -#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) +#define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) +#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) -#define ngcotouv(o) \ - check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) /* macro to convert any Lua object into a GCObject */ #define obj2gco(v) (cast(GCObject *, (v))) -LUAI_FUNC lua_State *luaE_newthread (lua_State *L); +/* actual number of total bytes allocated */ +#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) + +LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC void luaE_freeCI (lua_State *L); + #endif diff --git a/src/mod/languages/mod_lua/lua/lstring.c b/src/mod/languages/mod_lua/lua/lstring.c index 49113151cc..8b5af0b2e7 100644 --- a/src/mod/languages/mod_lua/lua/lstring.c +++ b/src/mod/languages/mod_lua/lua/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lstring.c,v 2.26 2013/01/08 13:50:10 roberto Exp $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -18,78 +18,157 @@ #include "lstring.h" +/* +** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to +** compute its hash +*/ +#if !defined(LUAI_HASHLIMIT) +#define LUAI_HASHLIMIT 5 +#endif -void luaS_resize (lua_State *L, int newsize) { - GCObject **newhash; - stringtable *tb; - int i; - if (G(L)->gcstate == GCSsweepstring) - return; /* cannot resize during GC traverse */ - newhash = luaM_newvector(L, newsize, GCObject *); - tb = &G(L)->strt; - for (i=0; isize; i++) { - GCObject *p = tb->hash[i]; - while (p) { /* for each node in the list */ - GCObject *next = p->gch.next; /* save next */ - unsigned int h = gco2ts(p)->hash; - int h1 = lmod(h, newsize); /* new position */ - lua_assert(cast_int(h%newsize) == lmod(h, newsize)); - p->gch.next = newhash[h1]; /* chain it */ - newhash[h1] = p; - p = next; - } - } - luaM_freearray(L, tb->hash, tb->size, TString *); - tb->size = newsize; - tb->hash = newhash; + +/* +** equality for long strings +*/ +int luaS_eqlngstr (TString *a, TString *b) { + size_t len = a->tsv.len; + lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); + return (a == b) || /* same instance or... */ + ((len == b->tsv.len) && /* equal length and ... */ + (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ } -static TString *newlstr (lua_State *L, const char *str, size_t l, - unsigned int h) { +/* +** equality for strings +*/ +int luaS_eqstr (TString *a, TString *b) { + return (a->tsv.tt == b->tsv.tt) && + (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); +} + + +unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { + unsigned int h = seed ^ cast(unsigned int, l); + size_t l1; + size_t step = (l >> LUAI_HASHLIMIT) + 1; + for (l1 = l; l1 >= step; l1 -= step) + h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); + return h; +} + + +/* +** resizes the string table +*/ +void luaS_resize (lua_State *L, int newsize) { + int i; + stringtable *tb = &G(L)->strt; + /* cannot resize while GC is traversing strings */ + luaC_runtilstate(L, ~bitmask(GCSsweepstring)); + if (newsize > tb->size) { + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; + } + /* rehash */ + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + tb->hash[i] = NULL; + while (p) { /* for each node in the list */ + GCObject *next = gch(p)->next; /* save next */ + unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ + gch(p)->next = tb->hash[h]; /* chain it */ + tb->hash[h] = p; + resetoldbit(p); /* see MOVE OLD rule */ + p = next; + } + } + if (newsize < tb->size) { + /* shrinking slice must be empty */ + lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + } + tb->size = newsize; +} + + +/* +** creates a new string object +*/ +static TString *createstrobj (lua_State *L, const char *str, size_t l, + int tag, unsigned int h, GCObject **list) { TString *ts; - stringtable *tb; - if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) - luaM_toobig(L); - ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); + size_t totalsize; /* total size of TString object */ + totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); + ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; ts->tsv.len = l; ts->tsv.hash = h; - ts->tsv.marked = luaC_white(G(L)); - ts->tsv.tt = LUA_TSTRING; - ts->tsv.reserved = 0; + ts->tsv.extra = 0; memcpy(ts+1, str, l*sizeof(char)); ((char *)(ts+1))[l] = '\0'; /* ending 0 */ - tb = &G(L)->strt; - h = lmod(h, tb->size); - ts->tsv.next = tb->hash[h]; /* chain new entry */ - tb->hash[h] = obj2gco(ts); - tb->nuse++; - if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) - luaS_resize(L, tb->size*2); /* too crowded */ return ts; } -TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { +/* +** creates a new short string, inserting it into string table +*/ +static TString *newshrstr (lua_State *L, const char *str, size_t l, + unsigned int h) { + GCObject **list; /* (pointer to) list where it will be inserted */ + stringtable *tb = &G(L)->strt; + TString *s; + if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + list = &tb->hash[lmod(h, tb->size)]; + s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); + tb->nuse++; + return s; +} + + +/* +** checks whether short string exists and reuses it or creates a new one +*/ +static TString *internshrstr (lua_State *L, const char *str, size_t l) { GCObject *o; - unsigned int h = cast(unsigned int, l); /* seed */ - size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ - size_t l1; - for (l1=l; l1>=step; l1-=step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); - for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; + global_State *g = G(L); + unsigned int h = luaS_hash(str, l, g->seed); + for (o = g->strt.hash[lmod(h, g->strt.size)]; o != NULL; - o = o->gch.next) { + o = gch(o)->next) { TString *ts = rawgco2ts(o); - if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { - /* string may be dead */ - if (isdead(G(L), o)) changewhite(o); + if (h == ts->tsv.hash && + l == ts->tsv.len && + (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { + if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ + changewhite(o); /* resurrect it */ return ts; } } - return newlstr(L, str, l, h); /* not found */ + return newshrstr(L, str, l, h); /* not found; create a new string */ +} + + +/* +** new string (with explicit length) +*/ +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + if (l <= LUAI_MAXSHORTLEN) /* short string? */ + return internshrstr(L, str, l); + else { + if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); + } +} + + +/* +** new zero-terminated string +*/ +TString *luaS_new (lua_State *L, const char *str) { + return luaS_newlstr(L, str, strlen(str)); } @@ -97,15 +176,10 @@ Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { Udata *u; if (s > MAX_SIZET - sizeof(Udata)) luaM_toobig(L); - u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); - u->uv.marked = luaC_white(G(L)); /* is not finalized */ - u->uv.tt = LUA_TUSERDATA; + u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; u->uv.len = s; u->uv.metatable = NULL; u->uv.env = e; - /* chain it on udata list (after main thread) */ - u->uv.next = G(L)->mainthread->next; - G(L)->mainthread->next = obj2gco(u); return u; } diff --git a/src/mod/languages/mod_lua/lua/lstring.h b/src/mod/languages/mod_lua/lua/lstring.h index 73a2ff8b38..d312ff3d2b 100644 --- a/src/mod/languages/mod_lua/lua/lstring.h +++ b/src/mod/languages/mod_lua/lua/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lstring.h,v 1.49 2012/02/01 21:57:15 roberto Exp $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -7,7 +7,6 @@ #ifndef lstring_h #define lstring_h - #include "lgc.h" #include "lobject.h" #include "lstate.h" @@ -17,15 +16,31 @@ #define sizeudata(u) (sizeof(union Udata)+(u)->len) -#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ (sizeof(s)/sizeof(char))-1)) #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + +/* +** test whether a string is a reserved word +*/ +#define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) + + +/* +** equality for short strings, which are always internalized +*/ +#define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) + + +LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC int luaS_eqstr (TString *a, TString *b); LUAI_FUNC void luaS_resize (lua_State *L, int newsize); LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); #endif diff --git a/src/mod/languages/mod_lua/lua/lstrlib.c b/src/mod/languages/mod_lua/lua/lstrlib.c index 1b4763d4ee..fcc61c9a62 100644 --- a/src/mod/languages/mod_lua/lua/lstrlib.c +++ b/src/mod/languages/mod_lua/lua/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ +** $Id: lstrlib.c,v 1.178 2012/08/14 18:12:34 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -20,47 +20,58 @@ #include "lualib.h" +/* +** maximum number of captures that a pattern can do during +** pattern-matching. This limit is arbitrary. +*/ +#if !defined(LUA_MAXCAPTURES) +#define LUA_MAXCAPTURES 32 +#endif + + /* macro to `unsign' a character */ -#define uchar(c) ((unsigned char)(c)) +#define uchar(c) ((unsigned char)(c)) static int str_len (lua_State *L) { size_t l; luaL_checklstring(L, 1, &l); - lua_pushinteger(L, l); + lua_pushinteger(L, (lua_Integer)l); return 1; } -static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { - /* relative string position: negative means back from end */ - if (pos < 0) pos += (ptrdiff_t)len + 1; - return (pos >= 0) ? pos : 0; +/* translate a relative string position: negative means back from end */ +static size_t posrelat (ptrdiff_t pos, size_t len) { + if (pos >= 0) return (size_t)pos; + else if (0u - (size_t)pos > len) return 0; + else return len - ((size_t)-pos) + 1; } static int str_sub (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); - ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); + size_t start = posrelat(luaL_checkinteger(L, 2), l); + size_t end = posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; - if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; + if (end > l) end = l; if (start <= end) - lua_pushlstring(L, s+start-1, end-start+1); + lua_pushlstring(L, s + start - 1, end - start + 1); else lua_pushliteral(L, ""); return 1; } static int str_reverse (lua_State *L) { - size_t l; + size_t l, i; luaL_Buffer b; const char *s = luaL_checklstring(L, 1, &l); - luaL_buffinit(L, &b); - while (l--) luaL_addchar(&b, s[l]); - luaL_pushresult(&b); + char *p = luaL_buffinitsize(L, &b, l); + for (i = 0; i < l; i++) + p[i] = s[l - i - 1]; + luaL_pushresultsize(&b, l); return 1; } @@ -70,10 +81,10 @@ static int str_lower (lua_State *L) { size_t i; luaL_Buffer b; const char *s = luaL_checklstring(L, 1, &l); - luaL_buffinit(L, &b); + char *p = luaL_buffinitsize(L, &b, l); for (i=0; i> 1) + static int str_rep (lua_State *L) { - size_t l; - luaL_Buffer b; + size_t l, lsep; const char *s = luaL_checklstring(L, 1, &l); int n = luaL_checkint(L, 2); - luaL_buffinit(L, &b); - while (n-- > 0) - luaL_addlstring(&b, s, l); - luaL_pushresult(&b); + const char *sep = luaL_optlstring(L, 3, "", &lsep); + if (n <= 0) lua_pushliteral(L, ""); + else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ + return luaL_error(L, "resulting string too large"); + else { + size_t totallen = n * l + (n - 1) * lsep; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, totallen); + while (n-- > 1) { /* first n-1 copies (followed by separator) */ + memcpy(p, s, l * sizeof(char)); p += l; + if (lsep > 0) { /* avoid empty 'memcpy' (may be expensive) */ + memcpy(p, sep, lsep * sizeof(char)); p += lsep; + } + } + memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ + luaL_pushresultsize(&b, totallen); + } return 1; } @@ -106,15 +133,15 @@ static int str_rep (lua_State *L) { static int str_byte (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); - ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + size_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + size_t pose = posrelat(luaL_optinteger(L, 3, posi), l); int n, i; - if (posi <= 0) posi = 1; - if ((size_t)pose > l) pose = l; + if (posi < 1) posi = 1; + if (pose > l) pose = l; if (posi > pose) return 0; /* empty interval; return no values */ n = (int)(pose - posi + 1); - if (posi + n <= pose) /* overflow? */ - luaL_error(L, "string slice too long"); + if (posi + n <= pose) /* (size_t -> int) overflow? */ + return luaL_error(L, "string slice too long"); luaL_checkstack(L, n, "string slice too long"); for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) - return luaL_error(ms->L, "invalid capture index"); + return luaL_error(ms->L, "invalid capture index %%%d", l + 1); return l; } @@ -202,16 +242,16 @@ static int capture_to_close (MatchState *ms) { static const char *classend (MatchState *ms, const char *p) { switch (*p++) { case L_ESC: { - if (*p == '\0') + if (p == ms->p_end) luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); return p+1; } case '[': { if (*p == '^') p++; do { /* look for a `]' */ - if (*p == '\0') + if (p == ms->p_end) luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); - if (*(p++) == L_ESC && *p != '\0') + if (*(p++) == L_ESC && p < ms->p_end) p++; /* skip escapes (e.g. `%]') */ } while (*p != ']'); return p+1; @@ -229,13 +269,14 @@ static int match_class (int c, int cl) { case 'a' : res = isalpha(c); break; case 'c' : res = iscntrl(c); break; case 'd' : res = isdigit(c); break; + case 'g' : res = isgraph(c); break; case 'l' : res = islower(c); break; case 'p' : res = ispunct(c); break; case 's' : res = isspace(c); break; case 'u' : res = isupper(c); break; case 'w' : res = isalnum(c); break; case 'x' : res = isxdigit(c); break; - case 'z' : res = (c == 0); break; + case 'z' : res = (c == 0); break; /* deprecated option */ default: return (cl == c); } return (islower(cl) ? res : !res); @@ -265,23 +306,27 @@ static int matchbracketclass (int c, const char *p, const char *ec) { } -static int singlematch (int c, const char *p, const char *ep) { - switch (*p) { - case '.': return 1; /* matches any char */ - case L_ESC: return match_class(c, uchar(*(p+1))); - case '[': return matchbracketclass(c, p, ep-1); - default: return (uchar(*p) == c); +static int singlematch (MatchState *ms, const char *s, const char *p, + const char *ep) { + if (s >= ms->src_end) + return 0; + else { + int c = uchar(*s); + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } } } -static const char *match (MatchState *ms, const char *s, const char *p); - - static const char *matchbalance (MatchState *ms, const char *s, const char *p) { - if (*p == 0 || *(p+1) == 0) - luaL_error(ms->L, "unbalanced pattern"); + if (p >= ms->p_end - 1) + luaL_error(ms->L, "malformed pattern " + "(missing arguments to " LUA_QL("%%b") ")"); if (*s != *p) return NULL; else { int b = *p; @@ -301,7 +346,7 @@ static const char *matchbalance (MatchState *ms, const char *s, static const char *max_expand (MatchState *ms, const char *s, const char *p, const char *ep) { ptrdiff_t i = 0; /* counts maximum expand for item */ - while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) + while (singlematch(ms, s + i, p, ep)) i++; /* keeps trying to match with the maximum repetitions */ while (i>=0) { @@ -319,7 +364,7 @@ static const char *min_expand (MatchState *ms, const char *s, const char *res = match(ms, s, ep+1); if (res != NULL) return res; - else if (ssrc_end && singlematch(uchar(*s), p, ep)) + else if (singlematch(ms, s, p, ep)) s++; /* try with one more repetition */ else return NULL; } @@ -363,80 +408,105 @@ static const char *match_capture (MatchState *ms, const char *s, int l) { static const char *match (MatchState *ms, const char *s, const char *p) { + if (ms->matchdepth-- == 0) + luaL_error(ms->L, "pattern too complex"); init: /* using goto's to optimize tail recursion */ - switch (*p) { - case '(': { /* start capture */ - if (*(p+1) == ')') /* position capture? */ - return start_capture(ms, s, p+2, CAP_POSITION); - else - return start_capture(ms, s, p+1, CAP_UNFINISHED); - } - case ')': { /* end capture */ - return end_capture(ms, s, p+1); - } - case L_ESC: { - switch (*(p+1)) { - case 'b': { /* balanced string? */ - s = matchbalance(ms, s, p+2); - if (s == NULL) return NULL; - p+=4; goto init; /* else return match(ms, s, p+4); */ - } - case 'f': { /* frontier? */ - const char *ep; char previous; - p += 2; - if (*p != '[') - luaL_error(ms->L, "missing " LUA_QL("[") " after " - LUA_QL("%%f") " in pattern"); - ep = classend(ms, p); /* points to what is next */ - previous = (s == ms->src_init) ? '\0' : *(s-1); - if (matchbracketclass(uchar(previous), p, ep-1) || - !matchbracketclass(uchar(*s), p, ep-1)) return NULL; - p=ep; goto init; /* else return match(ms, s, ep); */ - } - default: { - if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ - s = match_capture(ms, s, uchar(*(p+1))); - if (s == NULL) return NULL; - p+=2; goto init; /* else return match(ms, s, p+2) */ - } - goto dflt; /* case default */ - } + if (p != ms->p_end) { /* end of pattern? */ + switch (*p) { + case '(': { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; } - } - case '\0': { /* end of pattern */ - return s; /* match succeeded */ - } - case '$': { - if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ - return (s == ms->src_end) ? s : NULL; /* check end of string */ - else goto dflt; - } - default: dflt: { /* it is a pattern item */ - const char *ep = classend(ms, p); /* points to what is next */ - int m = ssrc_end && singlematch(uchar(*s), p, ep); - switch (*ep) { - case '?': { /* optional */ - const char *res; - if (m && ((res=match(ms, s+1, ep+1)) != NULL)) - return res; - p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + case ')': { /* end capture */ + s = end_capture(ms, s, p + 1); + break; + } + case '$': { + if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ + goto dflt; /* no; go to default */ + s = (s == ms->src_end) ? s : NULL; /* check end of string */ + break; + } + case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ + switch (*(p + 1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s != NULL) { + p += 4; goto init; /* return match(ms, s, p + 4); */ + } /* else fail (s == NULL) */ + break; + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && + matchbracketclass(uchar(*s), p, ep - 1)) { + p = ep; goto init; /* return match(ms, s, ep); */ + } + s = NULL; /* match failed */ + break; + } + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + case '8': case '9': { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) { + p += 2; goto init; /* return match(ms, s, p + 2) */ + } + break; + } + default: goto dflt; } - case '*': { /* 0 or more repetitions */ - return max_expand(ms, s, p, ep); + break; + } + default: dflt: { /* pattern class plus optional suffix */ + const char *ep = classend(ms, p); /* points to optional suffix */ + /* does not match at least once? */ + if (!singlematch(ms, s, p, ep)) { + if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ + p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ + } + else /* '+' or no suffix */ + s = NULL; /* fail */ } - case '+': { /* 1 or more repetitions */ - return (m ? max_expand(ms, s+1, p, ep) : NULL); - } - case '-': { /* 0 or more repetitions (minimum) */ - return min_expand(ms, s, p, ep); - } - default: { - if (!m) return NULL; - s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + else { /* matched once */ + switch (*ep) { /* handle optional suffix */ + case '?': { /* optional */ + const char *res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else { + p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ + } + break; + } + case '+': /* 1 or more repetitions */ + s++; /* 1 match already done */ + /* go through */ + case '*': /* 0 or more repetitions */ + s = max_expand(ms, s, p, ep); + break; + case '-': /* 0 or more repetitions (minimum) */ + s = min_expand(ms, s, p, ep); + break; + default: /* no suffix */ + s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ + } } + break; } } } + ms->matchdepth++; + return s; } @@ -492,37 +562,58 @@ static int push_captures (MatchState *ms, const char *s, const char *e) { } +/* check whether pattern has no special characters */ +static int nospecials (const char *p, size_t l) { + size_t upto = 0; + do { + if (strpbrk(p + upto, SPECIALS)) + return 0; /* pattern has a special character */ + upto += strlen(p + upto) + 1; /* may have more after \0 */ + } while (upto <= l); + return 1; /* no special chars found */ +} + + static int str_find_aux (lua_State *L, int find) { - size_t l1, l2; - const char *s = luaL_checklstring(L, 1, &l1); - const char *p = luaL_checklstring(L, 2, &l2); - ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; - if (init < 0) init = 0; - else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; - if (find && (lua_toboolean(L, 4) || /* explicit request? */ - strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); + if (init < 1) init = 1; + else if (init > ls + 1) { /* start after string's end? */ + lua_pushnil(L); /* cannot find anything */ + return 1; + } + /* explicit request or no special characters? */ + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { /* do a plain search */ - const char *s2 = lmemfind(s+init, l1-init, p, l2); + const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); if (s2) { - lua_pushinteger(L, s2-s+1); - lua_pushinteger(L, s2-s+l2); + lua_pushinteger(L, s2 - s + 1); + lua_pushinteger(L, s2 - s + lp); return 2; } } else { MatchState ms; - int anchor = (*p == '^') ? (p++, 1) : 0; - const char *s1=s+init; + const char *s1 = s + init - 1; + int anchor = (*p == '^'); + if (anchor) { + p++; lp--; /* skip anchor character */ + } ms.L = L; + ms.matchdepth = MAXCCALLS; ms.src_init = s; - ms.src_end = s+l1; + ms.src_end = s + ls; + ms.p_end = p + lp; do { const char *res; ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); if ((res=match(&ms, s1, p)) != NULL) { if (find) { - lua_pushinteger(L, s1-s+1); /* start */ - lua_pushinteger(L, res-s); /* end */ + lua_pushinteger(L, s1 - s + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ return push_captures(&ms, NULL, 0) + 2; } else @@ -547,18 +638,21 @@ static int str_match (lua_State *L) { static int gmatch_aux (lua_State *L) { MatchState ms; - size_t ls; + size_t ls, lp; const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); - const char *p = lua_tostring(L, lua_upvalueindex(2)); + const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); const char *src; ms.L = L; + ms.matchdepth = MAXCCALLS; ms.src_init = s; ms.src_end = s+ls; + ms.p_end = p + lp; for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); src <= ms.src_end; src++) { const char *e; ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); if ((e = match(&ms, src, p)) != NULL) { lua_Integer newstart = e-s; if (e == src) newstart++; /* empty match? go at least one position */ @@ -581,12 +675,6 @@ static int gmatch (lua_State *L) { } -static int gfind_nodef (lua_State *L) { - return luaL_error(L, LUA_QL("string.gfind") " was renamed to " - LUA_QL("string.gmatch")); -} - - static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, const char *e) { size_t l, i; @@ -596,8 +684,12 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, luaL_addchar(b, news[i]); else { i++; /* skip ESC */ - if (!isdigit(uchar(news[i]))) + if (!isdigit(uchar(news[i]))) { + if (news[i] != L_ESC) + luaL_error(ms->L, "invalid use of " LUA_QL("%c") + " in replacement string", L_ESC); luaL_addchar(b, news[i]); + } else if (news[i] == '0') luaL_addlstring(b, s, e - s); else { @@ -610,14 +702,9 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e) { + const char *e, int tr) { lua_State *L = ms->L; - switch (lua_type(L, 3)) { - case LUA_TNUMBER: - case LUA_TSTRING: { - add_s(ms, b, s, e); - return; - } + switch (tr) { case LUA_TFUNCTION: { int n; lua_pushvalue(L, 3); @@ -630,41 +717,51 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, lua_gettable(L, 3); break; } + default: { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); + return; + } } if (!lua_toboolean(L, -1)) { /* nil or false? */ lua_pop(L, 1); lua_pushlstring(L, s, e - s); /* keep original text */ } else if (!lua_isstring(L, -1)) - luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); luaL_addvalue(b); /* add result to accumulator */ } static int str_gsub (lua_State *L) { - size_t srcl; + size_t srcl, lp; const char *src = luaL_checklstring(L, 1, &srcl); - const char *p = luaL_checkstring(L, 2); - int tr = lua_type(L, 3); - int max_s = luaL_optint(L, 4, srcl+1); - int anchor = (*p == '^') ? (p++, 1) : 0; - int n = 0; + const char *p = luaL_checklstring(L, 2, &lp); + int tr = lua_type(L, 3); + size_t max_s = luaL_optinteger(L, 4, srcl+1); + int anchor = (*p == '^'); + size_t n = 0; MatchState ms; luaL_Buffer b; luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, "string/function/table expected"); luaL_buffinit(L, &b); + if (anchor) { + p++; lp--; /* skip anchor character */ + } ms.L = L; + ms.matchdepth = MAXCCALLS; ms.src_init = src; ms.src_end = src+srcl; + ms.p_end = p + lp; while (n < max_s) { const char *e; ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); e = match(&ms, src, p); if (e) { n++; - add_value(&ms, &b, src, e); + add_value(&ms, &b, src, e, tr); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ @@ -682,6 +779,46 @@ static int str_gsub (lua_State *L) { /* }====================================================== */ + +/* +** {====================================================== +** STRING FORMAT +** ======================================================= +*/ + +/* +** LUA_INTFRMLEN is the length modifier for integer conversions in +** 'string.format'; LUA_INTFRM_T is the integer type corresponding to +** the previous length +*/ +#if !defined(LUA_INTFRMLEN) /* { */ +#if defined(LUA_USE_LONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif +#endif /* } */ + + +/* +** LUA_FLTFRMLEN is the length modifier for float conversions in +** 'string.format'; LUA_FLTFRM_T is the float type corresponding to +** the previous length +*/ +#if !defined(LUA_FLTFRMLEN) + +#define LUA_FLTFRMLEN "" +#define LUA_FLTFRM_T double + +#endif + + /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ #define MAX_ITEM 512 /* valid flags in a format specification */ @@ -698,25 +835,20 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { const char *s = luaL_checklstring(L, arg, &l); luaL_addchar(b, '"'); while (l--) { - switch (*s) { - case '"': case '\\': case '\n': { - luaL_addchar(b, '\\'); - luaL_addchar(b, *s); - break; - } - case '\r': { - luaL_addlstring(b, "\\r", 2); - break; - } - case '\0': { - luaL_addlstring(b, "\\000", 4); - break; - } - default: { - luaL_addchar(b, *s); - break; - } + if (*s == '"' || *s == '\\' || *s == '\n') { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); } + else if (*s == '\0' || iscntrl(uchar(*s))) { + char buff[10]; + if (!isdigit(uchar(*(s+1)))) + sprintf(buff, "\\%d", (int)uchar(*s)); + else + sprintf(buff, "\\%03d", (int)uchar(*s)); + luaL_addstring(b, buff); + } + else + luaL_addchar(b, *s); s++; } luaL_addchar(b, '"'); @@ -725,7 +857,7 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { const char *p = strfrmt; while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ - if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) luaL_error(L, "invalid format (repeated flags)"); if (isdigit(uchar(*p))) p++; /* skip width */ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ @@ -737,23 +869,28 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { if (isdigit(uchar(*p))) luaL_error(L, "invalid format (width or precision too long)"); *(form++) = '%'; - strncpy(form, strfrmt, p - strfrmt + 1); + memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char)); form += p - strfrmt + 1; *form = '\0'; return p; } -static void addintlen (char *form) { +/* +** add length modifier into formats +*/ +static void addlenmod (char *form, const char *lenmod) { size_t l = strlen(form); + size_t lm = strlen(lenmod); char spec = form[l - 1]; - strcpy(form + l - 1, LUA_INTFRMLEN); - form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; - form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; + strcpy(form + l - 1, lenmod); + form[l + lm - 1] = spec; + form[l + lm] = '\0'; } static int str_format (lua_State *L) { + int top = lua_gettop(L); int arg = 1; size_t sfl; const char *strfrmt = luaL_checklstring(L, arg, &sfl); @@ -767,45 +904,61 @@ static int str_format (lua_State *L) { luaL_addchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ - char buff[MAX_ITEM]; /* to store the formatted item */ - arg++; + char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ + int nb = 0; /* number of bytes in added item */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); strfrmt = scanformat(L, strfrmt, form); switch (*strfrmt++) { case 'c': { - sprintf(buff, form, (int)luaL_checknumber(L, arg)); + nb = sprintf(buff, form, luaL_checkint(L, arg)); break; } - case 'd': case 'i': { - addintlen(form); - sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); + case 'd': case 'i': { + lua_Number n = luaL_checknumber(L, arg); + LUA_INTFRM_T ni = (LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = sprintf(buff, form, ni); break; } - case 'o': case 'u': case 'x': case 'X': { - addintlen(form); - sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); + case 'o': case 'u': case 'x': case 'X': { + lua_Number n = luaL_checknumber(L, arg); + unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a non-negative number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = sprintf(buff, form, ni); break; } - case 'e': case 'E': case 'f': + case 'e': case 'E': case 'f': +#if defined(LUA_USE_AFORMAT) + case 'a': case 'A': +#endif case 'g': case 'G': { - sprintf(buff, form, (double)luaL_checknumber(L, arg)); + addlenmod(form, LUA_FLTFRMLEN); + nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); break; } case 'q': { addquoted(L, &b, arg); - continue; /* skip the 'addsize' at the end */ + break; } case 's': { size_t l; - const char *s = luaL_checklstring(L, arg, &l); + const char *s = luaL_tolstring(L, arg, &l); if (!strchr(form, '.') && l >= 100) { /* no precision and string is too long to be formatted; keep original string */ - lua_pushvalue(L, arg); luaL_addvalue(&b); - continue; /* skip the `addsize' at the end */ + break; } else { - sprintf(buff, form, s); + nb = sprintf(buff, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ break; } } @@ -814,13 +967,15 @@ static int str_format (lua_State *L) { LUA_QL("format"), *(strfrmt - 1)); } } - luaL_addlstring(&b, buff, strlen(buff)); + luaL_addsize(&b, nb); } } luaL_pushresult(&b); return 1; } +/* }====================================================== */ + static const luaL_Reg strlib[] = { {"byte", str_byte}, @@ -828,7 +983,6 @@ static const luaL_Reg strlib[] = { {"dump", str_dump}, {"find", str_find}, {"format", str_format}, - {"gfind", gfind_nodef}, {"gmatch", gmatch}, {"gsub", str_gsub}, {"len", str_len}, @@ -843,13 +997,13 @@ static const luaL_Reg strlib[] = { static void createmetatable (lua_State *L) { - lua_createtable(L, 0, 1); /* create metatable for strings */ + lua_createtable(L, 0, 1); /* table to be metatable for strings */ lua_pushliteral(L, ""); /* dummy string */ - lua_pushvalue(L, -2); - lua_setmetatable(L, -2); /* set string metatable */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ lua_pop(L, 1); /* pop dummy string */ - lua_pushvalue(L, -2); /* string library... */ - lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, "__index"); /* metatable.__index = string */ lua_pop(L, 1); /* pop metatable */ } @@ -857,12 +1011,8 @@ static void createmetatable (lua_State *L) { /* ** Open string library */ -LUALIB_API int luaopen_string (lua_State *L) { - luaL_register(L, LUA_STRLIBNAME, strlib); -#if defined(LUA_COMPAT_GFIND) - lua_getfield(L, -1, "gmatch"); - lua_setfield(L, -2, "gfind"); -#endif +LUAMOD_API int luaopen_string (lua_State *L) { + luaL_newlib(L, strlib); createmetatable(L); return 1; } diff --git a/src/mod/languages/mod_lua/lua/ltable.c b/src/mod/languages/mod_lua/lua/ltable.c index ec84f4fabc..420391fc74 100644 --- a/src/mod/languages/mod_lua/lua/ltable.c +++ b/src/mod/languages/mod_lua/lua/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ +** $Id: ltable.c,v 2.72 2012/09/11 19:37:16 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -18,7 +18,6 @@ ** Hence even when the load factor reaches 100%, performance remains good. */ -#include #include #define ltable_c @@ -32,14 +31,16 @@ #include "lmem.h" #include "lobject.h" #include "lstate.h" +#include "lstring.h" #include "ltable.h" +#include "lvm.h" /* ** max size of array part is 2^MAXBITS */ -#if LUAI_BITSINT > 26 -#define MAXBITS 26 +#if LUAI_BITSINT >= 32 +#define MAXBITS 30 #else #define MAXBITS (LUAI_BITSINT-2) #endif @@ -47,10 +48,10 @@ #define MAXASIZE (1 << MAXBITS) -#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) - -#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) -#define hashboolean(t,p) hashpow2(t, p) +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) /* @@ -63,18 +64,13 @@ #define hashpointer(t,p) hashmod(t, IntPoint(p)) -/* -** number of ints inside a lua_Number -*/ -#define numints cast_int(sizeof(lua_Number)/sizeof(int)) - - - #define dummynode (&dummynode_) +#define isdummy(n) ((n) == dummynode) + static const Node dummynode_ = { - {{NULL}, LUA_TNIL}, /* value */ - {{{NULL}, LUA_TNIL, NULL}} /* key */ + {NILCONSTANT}, /* value */ + {{NILCONSTANT, NULL}} /* key */ }; @@ -82,13 +78,14 @@ static const Node dummynode_ = { ** hash for lua_Numbers */ static Node *hashnum (const Table *t, lua_Number n) { - unsigned int a[numints]; int i; - if (luai_numeq(n, 0)) /* avoid problems with -0 */ - return gnode(t, 0); - memcpy(a, &n, sizeof(a)); - for (i = 1; i < numints; i++) a[0] += a[i]; - return hashmod(t, a[0]); + luai_hashnum(i, n); + if (i < 0) { + if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */ + i = 0; /* handle INT_MIN */ + i = -i; /* must be a positive value */ + } + return hashmod(t, i); } @@ -101,12 +98,22 @@ static Node *mainposition (const Table *t, const TValue *key) { switch (ttype(key)) { case LUA_TNUMBER: return hashnum(t, nvalue(key)); - case LUA_TSTRING: + case LUA_TLNGSTR: { + TString *s = rawtsvalue(key); + if (s->tsv.extra == 0) { /* no hash? */ + s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); + s->tsv.extra = 1; /* now it has its hash */ + } + return hashstr(t, rawtsvalue(key)); + } + case LUA_TSHRSTR: return hashstr(t, rawtsvalue(key)); case LUA_TBOOLEAN: return hashboolean(t, bvalue(key)); case LUA_TLIGHTUSERDATA: return hashpointer(t, pvalue(key)); + case LUA_TLCF: + return hashpointer(t, fvalue(key)); default: return hashpointer(t, gcvalue(key)); } @@ -132,7 +139,7 @@ static int arrayindex (const TValue *key) { /* ** returns the index of a `key' for table traversals. First goes all ** elements in the array part, then elements in the hash part. The -** beginning of a traversal is signalled by -1. +** beginning of a traversal is signaled by -1. */ static int findindex (lua_State *L, Table *t, StkId key) { int i; @@ -142,19 +149,19 @@ static int findindex (lua_State *L, Table *t, StkId key) { return i-1; /* yes; that's the index (corrected to C) */ else { Node *n = mainposition(t, key); - do { /* check whether `key' is somewhere in the chain */ + for (;;) { /* check whether `key' is somewhere in the chain */ /* key may be dead already, but it is ok to use it in `next' */ - if (luaO_rawequalObj(key2tval(n), key) || - (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && - gcvalue(gkey(n)) == gcvalue(key))) { + if (luaV_rawequalobj(gkey(n), key) || + (ttisdeadkey(gkey(n)) && iscollectable(key) && + deadvalue(gkey(n)) == gcvalue(key))) { i = cast_int(n - gnode(t, 0)); /* key index in hash table */ /* hash elements are numbered after array ones */ return i + t->sizearray; } else n = gnext(n); - } while (n); - luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ - return 0; /* to avoid warnings */ + if (n == NULL) + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + } } } @@ -170,7 +177,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) { } for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ - setobj2s(L, key, key2tval(gnode(t, i))); + setobj2s(L, key, gkey(gnode(t, i))); setobj2s(L, key+1, gval(gnode(t, i))); return 1; } @@ -211,7 +218,7 @@ static int computesizes (int nums[], int *narray) { static int countint (const TValue *key, int *nums) { int k = arrayindex(key); if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ - nums[ceillog2(k)]++; /* count as such */ + nums[luaO_ceillog2(k)]++; /* count as such */ return 1; } else @@ -251,7 +258,7 @@ static int numusehash (const Table *t, int *nums, int *pnasize) { while (i--) { Node *n = &t->node[i]; if (!ttisnil(gval(n))) { - ause += countint(key2tval(n), nums); + ause += countint(gkey(n), nums); totaluse++; } } @@ -277,7 +284,7 @@ static void setnodevector (lua_State *L, Table *t, int size) { } else { int i; - lsize = ceillog2(size); + lsize = luaO_ceillog2(size); if (lsize > MAXBITS) luaG_runerror(L, "table overflow"); size = twoto(lsize); @@ -294,7 +301,7 @@ static void setnodevector (lua_State *L, Table *t, int size) { } -static void resize (lua_State *L, Table *t, int nasize, int nhsize) { +void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { int i; int oldasize = t->sizearray; int oldhsize = t->lsizenode; @@ -302,13 +309,13 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { if (nasize > oldasize) /* array part must grow? */ setarrayvector(L, t, nasize); /* create new hash part with appropriate size */ - setnodevector(L, t, nhsize); + setnodevector(L, t, nhsize); if (nasize < oldasize) { /* array part must shrink? */ t->sizearray = nasize; /* re-insert elements from vanishing slice */ for (i=nasize; iarray[i])) - setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); + luaH_setint(L, t, i + 1, &t->array[i]); } /* shrink array */ luaM_reallocvector(L, t->array, oldasize, nasize, TValue); @@ -316,23 +323,26 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { /* re-insert elements from hash part */ for (i = twoto(oldhsize) - 1; i >= 0; i--) { Node *old = nold+i; - if (!ttisnil(gval(old))) - setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); + if (!ttisnil(gval(old))) { + /* doesn't need barrier/invalidate cache, as entry was + already present in the table */ + setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); + } } - if (nold != dummynode) - luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ + if (!isdummy(nold)) + luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */ } void luaH_resizearray (lua_State *L, Table *t, int nasize) { - int nsize = (t->node == dummynode) ? 0 : sizenode(t); - resize(L, t, nasize, nsize); + int nsize = isdummy(t->node) ? 0 : sizenode(t); + luaH_resize(L, t, nasize, nsize); } static void rehash (lua_State *L, Table *t, const TValue *ek) { int nasize, na; - int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ + int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ int i; int totaluse; for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ @@ -345,7 +355,7 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) { /* compute new size for array part */ na = computesizes(nums, &nasize); /* resize the table to new computed sizes */ - resize(L, t, nasize, totaluse - na); + luaH_resize(L, t, nasize, totaluse - na); } @@ -355,32 +365,28 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) { */ -Table *luaH_new (lua_State *L, int narray, int nhash) { - Table *t = luaM_new(L, Table); - luaC_link(L, obj2gco(t), LUA_TTABLE); +Table *luaH_new (lua_State *L) { + Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; t->metatable = NULL; t->flags = cast_byte(~0); - /* temporary values (kept only if some malloc fails) */ t->array = NULL; t->sizearray = 0; - t->lsizenode = 0; - t->node = cast(Node *, dummynode); - setarrayvector(L, t, narray); - setnodevector(L, t, nhash); + setnodevector(L, t, 0); return t; } void luaH_free (lua_State *L, Table *t) { - if (t->node != dummynode) - luaM_freearray(L, t->node, sizenode(t), Node); - luaM_freearray(L, t->array, t->sizearray, TValue); + if (!isdummy(t->node)) + luaM_freearray(L, t->node, cast(size_t, sizenode(t))); + luaM_freearray(L, t->array, t->sizearray); luaM_free(L, t); } static Node *getfreepos (Table *t) { - while (t->lastfree-- > t->node) { + while (t->lastfree > t->node) { + t->lastfree--; if (ttisnil(gkey(t->lastfree))) return t->lastfree; } @@ -390,23 +396,28 @@ static Node *getfreepos (Table *t) { /* -** inserts a new key into a hash table; first, check whether key's main -** position is free. If not, check whether colliding node is in its main -** position or not: if it is not, move colliding node to an empty place and -** put new key in its main position; otherwise (colliding node is in its main -** position), new key goes to an empty position. +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. */ -static TValue *newkey (lua_State *L, Table *t, const TValue *key) { - Node *mp = mainposition(t, key); - if (!ttisnil(gval(mp)) || mp == dummynode) { +TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp; + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) + luaG_runerror(L, "table index is NaN"); + mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ Node *othern; Node *n = getfreepos(t); /* get a free place */ if (n == NULL) { /* cannot find a free place? */ rehash(L, t, key); /* grow table */ - return luaH_set(L, t, key); /* re-insert key into grown table */ + /* whatever called 'newkey' take care of TM cache and GC barrier */ + return luaH_set(L, t, key); /* insert key into grown table */ } - lua_assert(n != dummynode); - othern = mainposition(t, key2tval(mp)); + lua_assert(!isdummy(n)); + othern = mainposition(t, gkey(mp)); if (othern != mp) { /* is colliding node out of its main position? */ /* yes; move colliding node into free position */ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ @@ -422,8 +433,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { mp = n; } } - gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; - luaC_barriert(L, t, key); + setobj2t(L, gkey(mp), key); + luaC_barrierback(L, obj2gco(t), key); lua_assert(ttisnil(gval(mp))); return gval(mp); } @@ -432,7 +443,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { /* ** search function for integers */ -const TValue *luaH_getnum (Table *t, int key) { +const TValue *luaH_getint (Table *t, int key) { /* (1 <= key && key <= t->sizearray) */ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) return &t->array[key-1]; @@ -450,12 +461,13 @@ const TValue *luaH_getnum (Table *t, int key) { /* -** search function for strings +** search function for short strings */ const TValue *luaH_getstr (Table *t, TString *key) { Node *n = hashstr(t, key); + lua_assert(key->tsv.tt == LUA_TSHRSTR); do { /* check whether `key' is somewhere in the chain */ - if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) + if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) return gval(n); /* that's it */ else n = gnext(n); } while (n); @@ -468,20 +480,20 @@ const TValue *luaH_getstr (Table *t, TString *key) { */ const TValue *luaH_get (Table *t, const TValue *key) { switch (ttype(key)) { + case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); case LUA_TNIL: return luaO_nilobject; - case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); case LUA_TNUMBER: { int k; lua_Number n = nvalue(key); lua_number2int(k, n); - if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ - return luaH_getnum(t, k); /* use specialized version */ + if (luai_numeq(cast_num(k), n)) /* index is int? */ + return luaH_getint(t, k); /* use specialized version */ /* else go through */ } default: { Node *n = mainposition(t, key); do { /* check whether `key' is somewhere in the chain */ - if (luaO_rawequalObj(key2tval(n), key)) + if (luaV_rawequalobj(gkey(n), key)) return gval(n); /* that's it */ else n = gnext(n); } while (n); @@ -491,41 +503,29 @@ const TValue *luaH_get (Table *t, const TValue *key) { } +/* +** beware: when using this function you probably need to check a GC +** barrier and invalidate the TM cache. +*/ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { const TValue *p = luaH_get(t, key); - t->flags = 0; if (p != luaO_nilobject) return cast(TValue *, p); - else { - if (ttisnil(key)) luaG_runerror(L, "table index is nil"); - else if (ttisnumber(key) && luai_numisnan(nvalue(key))) - luaG_runerror(L, "table index is NaN"); - return newkey(L, t, key); - } + else return luaH_newkey(L, t, key); } -TValue *luaH_setnum (lua_State *L, Table *t, int key) { - const TValue *p = luaH_getnum(t, key); +void luaH_setint (lua_State *L, Table *t, int key, TValue *value) { + const TValue *p = luaH_getint(t, key); + TValue *cell; if (p != luaO_nilobject) - return cast(TValue *, p); + cell = cast(TValue *, p); else { TValue k; setnvalue(&k, cast_num(key)); - return newkey(L, t, &k); - } -} - - -TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { - const TValue *p = luaH_getstr(t, key); - if (p != luaO_nilobject) - return cast(TValue *, p); - else { - TValue k; - setsvalue(L, &k, key); - return newkey(L, t, &k); + cell = luaH_newkey(L, t, &k); } + setobj2t(L, cell, value); } @@ -533,20 +533,20 @@ static int unbound_search (Table *t, unsigned int j) { unsigned int i = j; /* i is zero or a present index */ j++; /* find `i' and `j' such that i is present and j is not */ - while (!ttisnil(luaH_getnum(t, j))) { + while (!ttisnil(luaH_getint(t, j))) { i = j; j *= 2; if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ /* table was built with bad purposes: resort to linear search */ i = 1; - while (!ttisnil(luaH_getnum(t, i))) i++; + while (!ttisnil(luaH_getint(t, i))) i++; return i - 1; } } /* now do a binary search between them */ while (j - i > 1) { unsigned int m = (i+j)/2; - if (ttisnil(luaH_getnum(t, m))) j = m; + if (ttisnil(luaH_getint(t, m))) j = m; else i = m; } return i; @@ -570,7 +570,7 @@ int luaH_getn (Table *t) { return i; } /* else must find a boundary in hash part */ - else if (t->node == dummynode) /* hash part is empty? */ + else if (isdummy(t->node)) /* hash part is empty? */ return j; /* that is easy... */ else return unbound_search(t, j); } @@ -583,6 +583,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) { return mainposition(t, key); } -int luaH_isdummy (Node *n) { return n == dummynode; } +int luaH_isdummy (Node *n) { return isdummy(n); } #endif diff --git a/src/mod/languages/mod_lua/lua/ltable.h b/src/mod/languages/mod_lua/lua/ltable.h index f5b9d5ead0..2f6f5c2dc8 100644 --- a/src/mod/languages/mod_lua/lua/ltable.h +++ b/src/mod/languages/mod_lua/lua/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -11,20 +11,21 @@ #define gnode(t,i) (&(t)->node[i]) -#define gkey(n) (&(n)->i_key.nk) +#define gkey(n) (&(n)->i_key.tvk) #define gval(n) (&(n)->i_val) #define gnext(n) ((n)->i_key.nk.next) -#define key2tval(n) (&(n)->i_key.tvk) +#define invalidateTMcache(t) ((t)->flags = 0) -LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); -LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); +LUAI_FUNC const TValue *luaH_getint (Table *t, int key); +LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value); LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); -LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); -LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); +LUAI_FUNC Table *luaH_new (lua_State *L); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); LUAI_FUNC void luaH_free (lua_State *L, Table *t); LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); diff --git a/src/mod/languages/mod_lua/lua/ltablib.c b/src/mod/languages/mod_lua/lua/ltablib.c index b6d9cb4ac7..ad798b4e2a 100644 --- a/src/mod/languages/mod_lua/lua/ltablib.c +++ b/src/mod/languages/mod_lua/lua/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ +** $Id: ltablib.c,v 1.65 2013/03/07 18:17:24 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -16,43 +16,11 @@ #include "lualib.h" -#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) -static int foreachi (lua_State *L) { - int i; - int n = aux_getn(L, 1); - luaL_checktype(L, 2, LUA_TFUNCTION); - for (i=1; i <= n; i++) { - lua_pushvalue(L, 2); /* function */ - lua_pushinteger(L, i); /* 1st argument */ - lua_rawgeti(L, 1, i); /* 2nd argument */ - lua_call(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 1); /* remove nil result */ - } - return 0; -} - - -static int foreach (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checktype(L, 2, LUA_TFUNCTION); - lua_pushnil(L); /* first key */ - while (lua_next(L, 1)) { - lua_pushvalue(L, 2); /* function */ - lua_pushvalue(L, -3); /* key */ - lua_pushvalue(L, -3); /* value */ - lua_call(L, 2, 1); - if (!lua_isnil(L, -1)) - return 1; - lua_pop(L, 2); /* remove value and result */ - } - return 0; -} - +#if defined(LUA_COMPAT_MAXN) static int maxn (lua_State *L) { lua_Number max = 0; luaL_checktype(L, 1, LUA_TTABLE); @@ -67,24 +35,7 @@ static int maxn (lua_State *L) { lua_pushnumber(L, max); return 1; } - - -static int getn (lua_State *L) { - lua_pushinteger(L, aux_getn(L, 1)); - return 1; -} - - -static int setn (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); -#ifndef luaL_setn - luaL_setn(L, 1, luaL_checkint(L, 2)); -#else - luaL_error(L, LUA_QL("setn") " is obsolete"); #endif - lua_pushvalue(L, 1); - return 1; -} static int tinsert (lua_State *L) { @@ -98,7 +49,7 @@ static int tinsert (lua_State *L) { case 3: { int i; pos = luaL_checkint(L, 2); /* 2nd argument is the position */ - if (pos > e) e = pos; /* `grow' array if necessary */ + luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); for (i = e; i > pos; i--) { /* move up elements */ lua_rawgeti(L, 1, i-1); lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ @@ -109,25 +60,23 @@ static int tinsert (lua_State *L) { return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); } } - luaL_setn(L, 1, e); /* new size */ lua_rawseti(L, 1, pos); /* t[pos] = v */ return 0; } static int tremove (lua_State *L) { - int e = aux_getn(L, 1); - int pos = luaL_optint(L, 2, e); - if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ - return 0; /* nothing to remove */ - luaL_setn(L, 1, e - 1); /* t.n = n-1 */ + int size = aux_getn(L, 1); + int pos = luaL_optint(L, 2, size); + if (pos != size) /* validate 'pos' if given */ + luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); lua_rawgeti(L, 1, pos); /* result = t[pos] */ - for ( ;pos 0) { /* at least one element? */ + int i; + lua_pushvalue(L, 1); + lua_rawseti(L, -2, 1); /* insert first element */ + lua_replace(L, 1); /* move table into index 1 */ + for (i = n; i >= 2; i--) /* assign other elements */ + lua_rawseti(L, 1, i); + } + return 1; /* return table */ +} + + +static int unpack (lua_State *L) { + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); + if (i > e) return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + +/* }====================================================== */ + + /* ** {====================================================== ** Quicksort ** (based on `Algorithms in MODULA-3', Robert Sedgewick; ** Addison-Wesley, 1993.) +** ======================================================= */ @@ -187,7 +178,7 @@ static int sort_comp (lua_State *L, int a, int b) { return res; } else /* a < b? */ - return lua_lessthan(L, a, b); + return lua_compare(L, a, b, LUA_OPLT); } static void auxsort (lua_State *L, int l, int u) { @@ -224,12 +215,12 @@ static void auxsort (lua_State *L, int l, int u) { for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ /* repeat ++i until a[i] >= P */ while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { - if (i>u) luaL_error(L, "invalid order function for sorting"); + if (i>=u) luaL_error(L, "invalid order function for sorting"); lua_pop(L, 1); /* remove a[i] */ } /* repeat --j until a[j] <= P */ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { - if (jmetatable; break; @@ -68,7 +70,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { mt = uvalue(o)->metatable; break; default: - mt = G(L)->mt[ttype(o)]; + mt = G(L)->mt[ttypenv(o)]; } return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); } diff --git a/src/mod/languages/mod_lua/lua/ltm.h b/src/mod/languages/mod_lua/lua/ltm.h index 64343b781b..89bdc19a1e 100644 --- a/src/mod/languages/mod_lua/lua/ltm.h +++ b/src/mod/languages/mod_lua/lua/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: ltm.h,v 2.11 2011/02/28 17:32:10 roberto Exp $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -20,6 +20,7 @@ typedef enum { TM_NEWINDEX, TM_GC, TM_MODE, + TM_LEN, TM_EQ, /* last tag method with `fast' access */ TM_ADD, TM_SUB, @@ -28,7 +29,6 @@ typedef enum { TM_MOD, TM_POW, TM_UNM, - TM_LEN, TM_LT, TM_LE, TM_CONCAT, @@ -43,7 +43,10 @@ typedef enum { #define fasttm(l,et,e) gfasttm(G(l), et, e) -LUAI_DATA const char *const luaT_typenames[]; +#define ttypename(x) luaT_typenames_[(x) + 1] +#define objtypename(x) ttypename(ttypenv(x)) + +LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); diff --git a/src/mod/languages/mod_lua/lua/lua.c b/src/mod/languages/mod_lua/lua/lua.c index 3a46609328..6a00712920 100644 --- a/src/mod/languages/mod_lua/lua/lua.c +++ b/src/mod/languages/mod_lua/lua/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ +** $Id: lua.c,v 1.206 2012/09/29 20:07:06 roberto Exp $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -18,6 +18,72 @@ #include "lualib.h" +#if !defined(LUA_PROMPT) +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " +#endif + +#if !defined(LUA_PROGNAME) +#define LUA_PROGNAME "lua" +#endif + +#if !defined(LUA_MAXINPUT) +#define LUA_MAXINPUT 512 +#endif + +#if !defined(LUA_INIT) +#define LUA_INIT "LUA_INIT" +#endif + +#define LUA_INITVERSION \ + LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + + +/* +** lua_stdin_is_tty detects whether the standard input is a 'tty' (that +** is, whether we're running lua interactively). +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +** lua_readline defines how to show a prompt and then read a line from +** the standard input. +** lua_saveline defines how to "save" a read line in a "history". +** lua_freeline defines how to free a line read by lua_readline. +*/ +#if defined(LUA_USE_READLINE) + +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) + +#elif !defined(lua_readline) + +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } + +#endif + + + static lua_State *globalL = NULL; @@ -39,77 +105,87 @@ static void laction (int i) { } -static void print_usage (void) { - fprintf(stderr, - "usage: %s [options] [script [args]].\n" +static void print_usage (const char *badoption) { + luai_writestringerror("%s: ", progname); + if (badoption[1] == 'e' || badoption[1] == 'l') + luai_writestringerror("'%s' needs argument\n", badoption); + else + luai_writestringerror("unrecognized option '%s'\n", badoption); + luai_writestringerror( + "usage: %s [options] [script [args]]\n" "Available options are:\n" " -e stat execute string " LUA_QL("stat") "\n" - " -l name require library " LUA_QL("name") "\n" " -i enter interactive mode after executing " LUA_QL("script") "\n" + " -l name require library " LUA_QL("name") "\n" " -v show version information\n" + " -E ignore environment variables\n" " -- stop handling options\n" - " - execute stdin and stop handling options\n" + " - stop handling options and execute stdin\n" , progname); - fflush(stderr); } static void l_message (const char *pname, const char *msg) { - if (pname) fprintf(stderr, "%s: ", pname); - fprintf(stderr, "%s\n", msg); - fflush(stderr); + if (pname) luai_writestringerror("%s: ", pname); + luai_writestringerror("%s\n", msg); } static int report (lua_State *L, int status) { - if (status && !lua_isnil(L, -1)) { + if (status != LUA_OK && !lua_isnil(L, -1)) { const char *msg = lua_tostring(L, -1); if (msg == NULL) msg = "(error object is not a string)"; l_message(progname, msg); lua_pop(L, 1); + /* force a complete garbage collection in case of errors */ + lua_gc(L, LUA_GCCOLLECT, 0); } return status; } -static int traceback (lua_State *L) { - if (!lua_isstring(L, 1)) /* 'message' not a string? */ - return 1; /* keep it intact */ - lua_getfield(L, LUA_GLOBALSINDEX, "debug"); - if (!lua_istable(L, -1)) { +/* the next function is called unprotected, so it must avoid errors */ +static void finalreport (lua_State *L, int status) { + if (status != LUA_OK) { + const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1) + : NULL; + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); lua_pop(L, 1); - return 1; } - lua_getfield(L, -1, "traceback"); - if (!lua_isfunction(L, -1)) { - lua_pop(L, 2); - return 1; +} + + +static int traceback (lua_State *L) { + const char *msg = lua_tostring(L, 1); + if (msg) + luaL_traceback(L, L, msg, 1); + else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */ + if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */ + lua_pushliteral(L, "(no error message)"); } - lua_pushvalue(L, 1); /* pass error message */ - lua_pushinteger(L, 2); /* skip this function and traceback */ - lua_call(L, 2, 1); /* call debug.traceback */ return 1; } -static int docall (lua_State *L, int narg, int clear) { +static int docall (lua_State *L, int narg, int nres) { int status; int base = lua_gettop(L) - narg; /* function index */ lua_pushcfunction(L, traceback); /* push traceback function */ lua_insert(L, base); /* put it under chunk and args */ + globalL = L; /* to be available to 'laction' */ signal(SIGINT, laction); - status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); + status = lua_pcall(L, narg, nres, base); signal(SIGINT, SIG_DFL); lua_remove(L, base); /* remove traceback function */ - /* force a complete garbage collection in case of errors */ - if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); return status; } static void print_version (void) { - l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); + luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); + luai_writeline(); } @@ -132,40 +208,47 @@ static int getargs (lua_State *L, char **argv, int n) { static int dofile (lua_State *L, const char *name) { - int status = luaL_loadfile(L, name) || docall(L, 0, 1); + int status = luaL_loadfile(L, name); + if (status == LUA_OK) status = docall(L, 0, 0); return report(L, status); } static int dostring (lua_State *L, const char *s, const char *name) { - int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); + int status = luaL_loadbuffer(L, s, strlen(s), name); + if (status == LUA_OK) status = docall(L, 0, 0); return report(L, status); } static int dolibrary (lua_State *L, const char *name) { + int status; lua_getglobal(L, "require"); lua_pushstring(L, name); - return report(L, docall(L, 1, 1)); + status = docall(L, 1, 1); /* call 'require(name)' */ + if (status == LUA_OK) + lua_setglobal(L, name); /* global[name] = require return */ + return report(L, status); } static const char *get_prompt (lua_State *L, int firstline) { const char *p; - lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); + lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); p = lua_tostring(L, -1); if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); - lua_pop(L, 1); /* remove global */ return p; } +/* mark in error messages for incomplete statements */ +#define EOFMARK "" +#define marklen (sizeof(EOFMARK)/sizeof(char) - 1) static int incomplete (lua_State *L, int status) { if (status == LUA_ERRSYNTAX) { size_t lmsg; const char *msg = lua_tolstring(L, -1, &lmsg); - const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); - if (strstr(msg, LUA_QL("")) == tp) { + if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { lua_pop(L, 1); return 1; } @@ -179,7 +262,9 @@ static int pushline (lua_State *L, int firstline) { char *b = buffer; size_t l; const char *prmt = get_prompt(L, firstline); - if (lua_readline(L, b, prmt) == 0) + int readstatus = lua_readline(L, b, prmt); + lua_pop(L, 1); /* remove result from 'get_prompt' */ + if (readstatus == 0) return 0; /* no input */ l = strlen(b); if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ @@ -199,7 +284,9 @@ static int loadline (lua_State *L) { if (!pushline(L, 1)) return -1; /* no input */ for (;;) { /* repeat until gets a complete line */ - status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + size_t l; + const char *line = lua_tolstring(L, 1, &l); + status = luaL_loadbuffer(L, line, l, "=stdin"); if (!incomplete(L, status)) break; /* cannot try to add lines? */ if (!pushline(L, 0)) /* no more input? */ return -1; @@ -218,20 +305,20 @@ static void dotty (lua_State *L) { const char *oldprogname = progname; progname = NULL; while ((status = loadline(L)) != -1) { - if (status == 0) status = docall(L, 0, 0); + if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET); report(L, status); - if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ + luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); lua_getglobal(L, "print"); lua_insert(L, 1); - if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) l_message(progname, lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)", lua_tostring(L, -1))); } } lua_settop(L, 0); /* clear stack */ - fputs("\n", stdout); - fflush(stdout); + luai_writeline(); progname = oldprogname; } @@ -242,49 +329,63 @@ static int handle_script (lua_State *L, char **argv, int n) { int narg = getargs(L, argv, n); /* collect arguments */ lua_setglobal(L, "arg"); fname = argv[n]; - if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) fname = NULL; /* stdin */ status = luaL_loadfile(L, fname); lua_insert(L, -(narg+1)); - if (status == 0) - status = docall(L, narg, 0); + if (status == LUA_OK) + status = docall(L, narg, LUA_MULTRET); else - lua_pop(L, narg); + lua_pop(L, narg); return report(L, status); } /* check that argument has no extra characters at the end */ -#define notail(x) {if ((x)[2] != '\0') return -1;} +#define noextrachars(x) {if ((x)[2] != '\0') return -1;} -static int collectargs (char **argv, int *pi, int *pv, int *pe) { +/* indices of various argument indicators in array args */ +#define has_i 0 /* -i */ +#define has_v 1 /* -v */ +#define has_e 2 /* -e */ +#define has_E 3 /* -E */ + +#define num_has 4 /* number of 'has_*' */ + + +static int collectargs (char **argv, int *args) { int i; for (i = 1; argv[i] != NULL; i++) { if (argv[i][0] != '-') /* not an option? */ return i; switch (argv[i][1]) { /* option */ case '-': - notail(argv[i]); + noextrachars(argv[i]); return (argv[i+1] != NULL ? i+1 : 0); case '\0': return i; + case 'E': + args[has_E] = 1; + break; case 'i': - notail(argv[i]); - *pi = 1; /* go through */ + noextrachars(argv[i]); + args[has_i] = 1; /* go through */ case 'v': - notail(argv[i]); - *pv = 1; + noextrachars(argv[i]); + args[has_v] = 1; break; case 'e': - *pe = 1; /* go through */ - case 'l': - if (argv[i][2] == '\0') { - i++; - if (argv[i] == NULL) return -1; + args[has_e] = 1; /* go through */ + case 'l': /* both options need an argument */ + if (argv[i][2] == '\0') { /* no concatenated argument? */ + i++; /* try next 'argv' */ + if (argv[i] == NULL || argv[i][0] == '-') + return -(i - 1); /* no next argument or it is another option */ } break; - default: return -1; /* invalid option */ + default: /* invalid option; return its index... */ + return -i; /* ...as a negative value */ } } return 0; @@ -294,99 +395,103 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) { static int runargs (lua_State *L, char **argv, int n) { int i; for (i = 1; i < n; i++) { - if (argv[i] == NULL) continue; lua_assert(argv[i][0] == '-'); switch (argv[i][1]) { /* option */ case 'e': { const char *chunk = argv[i] + 2; if (*chunk == '\0') chunk = argv[++i]; lua_assert(chunk != NULL); - if (dostring(L, chunk, "=(command line)") != 0) - return 1; + if (dostring(L, chunk, "=(command line)") != LUA_OK) + return 0; break; } case 'l': { const char *filename = argv[i] + 2; if (*filename == '\0') filename = argv[++i]; lua_assert(filename != NULL); - if (dolibrary(L, filename)) - return 1; /* stop if file fails */ + if (dolibrary(L, filename) != LUA_OK) + return 0; /* stop if file fails */ break; } default: break; } } - return 0; + return 1; } static int handle_luainit (lua_State *L) { - const char *init = getenv(LUA_INIT); - if (init == NULL) return 0; /* status OK */ + const char *name = "=" LUA_INITVERSION; + const char *init = getenv(name + 1); + if (init == NULL) { + name = "=" LUA_INIT; + init = getenv(name + 1); /* try alternative name */ + } + if (init == NULL) return LUA_OK; else if (init[0] == '@') return dofile(L, init+1); else - return dostring(L, init, "=" LUA_INIT); + return dostring(L, init, name); } -struct Smain { - int argc; - char **argv; - int status; -}; - - static int pmain (lua_State *L) { - struct Smain *s = (struct Smain *)lua_touserdata(L, 1); - char **argv = s->argv; + int argc = (int)lua_tointeger(L, 1); + char **argv = (char **)lua_touserdata(L, 2); int script; - int has_i = 0, has_v = 0, has_e = 0; - globalL = L; + int args[num_has]; + args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0; if (argv[0] && argv[0][0]) progname = argv[0]; + script = collectargs(argv, args); + if (script < 0) { /* invalid arg? */ + print_usage(argv[-script]); + return 0; + } + if (args[has_v]) print_version(); + if (args[has_E]) { /* option '-E'? */ + lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + } + /* open standard libraries */ + luaL_checkversion(L); lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ luaL_openlibs(L); /* open libraries */ lua_gc(L, LUA_GCRESTART, 0); - s->status = handle_luainit(L); - if (s->status != 0) return 0; - script = collectargs(argv, &has_i, &has_v, &has_e); - if (script < 0) { /* invalid args? */ - print_usage(); - s->status = 1; - return 0; - } - if (has_v) print_version(); - s->status = runargs(L, argv, (script > 0) ? script : s->argc); - if (s->status != 0) return 0; - if (script) - s->status = handle_script(L, argv, script); - if (s->status != 0) return 0; - if (has_i) + if (!args[has_E] && handle_luainit(L) != LUA_OK) + return 0; /* error running LUA_INIT */ + /* execute arguments -e and -l */ + if (!runargs(L, argv, (script > 0) ? script : argc)) return 0; + /* execute main script (if there is one) */ + if (script && handle_script(L, argv, script) != LUA_OK) return 0; + if (args[has_i]) /* -i option? */ dotty(L); - else if (script == 0 && !has_e && !has_v) { + else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */ if (lua_stdin_is_tty()) { print_version(); dotty(L); } else dofile(L, NULL); /* executes stdin as a file */ } - return 0; + lua_pushboolean(L, 1); /* signal no errors */ + return 1; } int main (int argc, char **argv) { - int status; - struct Smain s; - lua_State *L = lua_open(); /* create state */ + int status, result; + lua_State *L = luaL_newstate(); /* create state */ if (L == NULL) { l_message(argv[0], "cannot create state: not enough memory"); return EXIT_FAILURE; } - s.argc = argc; - s.argv = argv; - status = lua_cpcall(L, &pmain, &s); - report(L, status); + /* call 'pmain' in protected mode */ + lua_pushcfunction(L, &pmain); + lua_pushinteger(L, argc); /* 1st argument */ + lua_pushlightuserdata(L, argv); /* 2nd argument */ + status = lua_pcall(L, 2, 1, 0); + result = lua_toboolean(L, -1); /* get result */ + finalreport(L, status); lua_close(L); - return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; + return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/src/mod/languages/mod_lua/lua/lua.h b/src/mod/languages/mod_lua/lua/lua.h index e4bdfd3b94..eb0482b8f4 100644 --- a/src/mod/languages/mod_lua/lua/lua.h +++ b/src/mod/languages/mod_lua/lua/lua.h @@ -1,6 +1,6 @@ /* -** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ -** Lua - An Extensible Extension Language +** $Id: lua.h,v 1.285 2013/03/15 13:04:22 roberto Exp $ +** Lua - A Scripting Language ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) ** See Copyright Notice at the end of this file */ @@ -16,35 +16,39 @@ #include "luaconf.h" -#define LUA_VERSION "Lua 5.1" -#define LUA_RELEASE "Lua 5.1.4" -#define LUA_VERSION_NUM 501 -#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" -#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "2" +#define LUA_VERSION_NUM 502 +#define LUA_VERSION_RELEASE "2" + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" -/* mark for precompiled code (`Lua') */ -#define LUA_SIGNATURE "\033Lua" +/* mark for precompiled code ('Lua') */ +#define LUA_SIGNATURE "\033Lua" -/* option for multiple returns in `lua_pcall' and `lua_call' */ +/* option for multiple returns in 'lua_pcall' and 'lua_call' */ #define LUA_MULTRET (-1) /* ** pseudo-indices */ -#define LUA_REGISTRYINDEX (-10000) -#define LUA_ENVIRONINDEX (-10001) -#define LUA_GLOBALSINDEX (-10002) -#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) +#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) -/* thread status; 0 is OK */ +/* thread status */ +#define LUA_OK 0 #define LUA_YIELD 1 #define LUA_ERRRUN 2 #define LUA_ERRSYNTAX 3 #define LUA_ERRMEM 4 -#define LUA_ERRERR 5 +#define LUA_ERRGCMM 5 +#define LUA_ERRERR 6 typedef struct lua_State lua_State; @@ -81,12 +85,32 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); #define LUA_TUSERDATA 7 #define LUA_TTHREAD 8 +#define LUA_NUMTAGS 9 + /* minimum Lua stack available to a C function */ #define LUA_MINSTACK 20 +/* predefined values in the registry */ +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + + + /* ** generic extra include file */ @@ -95,13 +119,10 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); #endif -/* type of numbers in Lua */ -typedef LUA_NUMBER lua_Number; - - -/* type for integer functions */ -typedef LUA_INTEGER lua_Integer; - +/* +** RCS ident string +*/ +extern const char lua_ident[]; /* @@ -114,15 +135,20 @@ LUA_API lua_State *(lua_newthread) (lua_State *L); LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); +LUA_API const lua_Number *(lua_version) (lua_State *L); + + /* ** basic stack manipulation */ +LUA_API int (lua_absindex) (lua_State *L, int idx); LUA_API int (lua_gettop) (lua_State *L); LUA_API void (lua_settop) (lua_State *L, int idx); LUA_API void (lua_pushvalue) (lua_State *L, int idx); LUA_API void (lua_remove) (lua_State *L, int idx); LUA_API void (lua_insert) (lua_State *L, int idx); LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); LUA_API int (lua_checkstack) (lua_State *L, int sz); LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); @@ -139,29 +165,49 @@ LUA_API int (lua_isuserdata) (lua_State *L, int idx); LUA_API int (lua_type) (lua_State *L, int idx); LUA_API const char *(lua_typename) (lua_State *L, int tp); -LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); -LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); -LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); - -LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); -LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum); LUA_API int (lua_toboolean) (lua_State *L, int idx); LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); -LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API size_t (lua_rawlen) (lua_State *L, int idx); LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); LUA_API void *(lua_touserdata) (lua_State *L, int idx); LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); LUA_API const void *(lua_topointer) (lua_State *L, int idx); +/* +** Comparison and arithmetic functions +*/ + +#define LUA_OPADD 0 /* ORDER TM */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPDIV 3 +#define LUA_OPMOD 4 +#define LUA_OPPOW 5 +#define LUA_OPUNM 6 + +LUA_API void (lua_arith) (lua_State *L, int op); + +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 + +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); + + /* ** push functions (C -> stack) */ -LUA_API void (lua_pushnil) (lua_State *L); -LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); -LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); -LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); -LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n); +LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, va_list argp); LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); @@ -174,35 +220,47 @@ LUA_API int (lua_pushthread) (lua_State *L); /* ** get functions (Lua -> stack) */ +LUA_API void (lua_getglobal) (lua_State *L, const char *var); LUA_API void (lua_gettable) (lua_State *L, int idx); LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); LUA_API void (lua_rawget) (lua_State *L, int idx); LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p); LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); LUA_API int (lua_getmetatable) (lua_State *L, int objindex); -LUA_API void (lua_getfenv) (lua_State *L, int idx); +LUA_API void (lua_getuservalue) (lua_State *L, int idx); /* ** set functions (stack -> Lua) */ +LUA_API void (lua_setglobal) (lua_State *L, const char *var); LUA_API void (lua_settable) (lua_State *L, int idx); LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); LUA_API void (lua_rawset) (lua_State *L, int idx); LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); LUA_API int (lua_setmetatable) (lua_State *L, int objindex); -LUA_API int (lua_setfenv) (lua_State *L, int idx); +LUA_API void (lua_setuservalue) (lua_State *L, int idx); /* -** `load' and `call' functions (load and run Lua code) +** 'load' and 'call' functions (load and run Lua code) */ -LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); -LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); -LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k); +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +LUA_API int (lua_getctx) (lua_State *L, int *ctx); + +LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k); +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) + LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, - const char *chunkname); + const char *chunkname, + const char *mode); LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); @@ -210,8 +268,10 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); /* ** coroutine functions */ -LUA_API int (lua_yield) (lua_State *L, int nresults); -LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx, + lua_CFunction k); +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) +LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); LUA_API int (lua_status) (lua_State *L); /* @@ -226,6 +286,10 @@ LUA_API int (lua_status) (lua_State *L); #define LUA_GCSTEP 5 #define LUA_GCSETPAUSE 6 #define LUA_GCSETSTEPMUL 7 +#define LUA_GCSETMAJORINC 8 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 LUA_API int (lua_gc) (lua_State *L, int what, int data); @@ -239,18 +303,23 @@ LUA_API int (lua_error) (lua_State *L); LUA_API int (lua_next) (lua_State *L, int idx); LUA_API void (lua_concat) (lua_State *L, int n); +LUA_API void (lua_len) (lua_State *L, int idx); LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); -LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); +LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); -/* +/* ** =============================================================== ** some useful macros ** =============================================================== */ +#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) +#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) + #define lua_pop(L,n) lua_settop(L, -(n)-1) #define lua_newtable(L) lua_createtable(L, 0, 0) @@ -259,8 +328,6 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) -#define lua_strlen(L,i) lua_objlen(L, (i)) - #define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) #define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) #define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) @@ -273,31 +340,13 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); #define lua_pushliteral(L, s) \ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) -#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) -#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_pushglobaltable(L) \ + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) #define lua_tostring(L,i) lua_tolstring(L, (i), NULL) -/* -** compatibility macros and functions -*/ - -#define lua_open() luaL_newstate() - -#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) - -#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) - -#define lua_Chunkreader lua_Reader -#define lua_Chunkwriter lua_Writer - - -/* hack */ -LUA_API void lua_setlevel (lua_State *from, lua_State *to); - - /* ** {====================================================================== ** Debug API @@ -312,7 +361,7 @@ LUA_API void lua_setlevel (lua_State *from, lua_State *to); #define LUA_HOOKRET 1 #define LUA_HOOKLINE 2 #define LUA_HOOKCOUNT 3 -#define LUA_HOOKTAILRET 4 +#define LUA_HOOKTAILCALL 4 /* @@ -326,43 +375,50 @@ LUA_API void lua_setlevel (lua_State *from, lua_State *to); typedef struct lua_Debug lua_Debug; /* activation record */ -/* Functions to be called by the debuger in specific events */ +/* Functions to be called by the debugger in specific events */ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); -LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); -LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); -LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); -LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); +LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); +LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); +LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); -LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); -LUA_API lua_Hook lua_gethook (lua_State *L); -LUA_API int lua_gethookmask (lua_State *L); -LUA_API int lua_gethookcount (lua_State *L); +LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); +LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, + int fidx2, int n2); + +LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook (lua_gethook) (lua_State *L); +LUA_API int (lua_gethookmask) (lua_State *L); +LUA_API int (lua_gethookcount) (lua_State *L); struct lua_Debug { int event; const char *name; /* (n) */ - const char *namewhat; /* (n) `global', `local', `field', `method' */ - const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ const char *source; /* (S) */ int currentline; /* (l) */ - int nups; /* (u) number of upvalues */ int linedefined; /* (S) */ int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams;/* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ - int i_ci; /* active function */ + struct CallInfo *i_ci; /* active function */ }; /* }====================================================================== */ /****************************************************************************** -* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. +* Copyright (C) 1994-2013 Lua.org, PUC-Rio. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the diff --git a/src/mod/languages/mod_lua/lua/luac.c b/src/mod/languages/mod_lua/lua/luac.c index d07017391b..5081836d4c 100644 --- a/src/mod/languages/mod_lua/lua/luac.c +++ b/src/mod/languages/mod_lua/lua/luac.c @@ -1,5 +1,5 @@ /* -** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ +** $Id: luac.c,v 1.69 2011/11/29 17:46:33 lhf Exp $ ** Lua compiler (saves bytecodes to files; also list bytecodes) ** See Copyright Notice in lua.h */ @@ -15,16 +15,15 @@ #include "lua.h" #include "lauxlib.h" -#include "ldo.h" -#include "lfunc.h" -#include "lmem.h" #include "lobject.h" -#include "lopcodes.h" -#include "lstring.h" +#include "lstate.h" #include "lundump.h" +static void PrintFunction(const Proto* f, int full); +#define luaU_print PrintFunction + #define PROGNAME "luac" /* default program name */ -#define OUTPUT PROGNAME ".out" /* default output file */ +#define OUTPUT PROGNAME ".out" /* default output file */ static int listing=0; /* list bytecodes? */ static int dumping=1; /* dump bytecodes? */ @@ -52,20 +51,20 @@ static void usage(const char* message) else fprintf(stderr,"%s: %s\n",progname,message); fprintf(stderr, - "usage: %s [options] [filenames].\n" - "Available options are:\n" - " - process stdin\n" - " -l list\n" - " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" - " -p parse only\n" - " -s strip debug information\n" - " -v show version information\n" - " -- stop handling options\n", - progname,Output); + "usage: %s [options] [filenames]\n" + "Available options are:\n" + " -l list (use -l -l for full listing)\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n" + " - stop handling options and process stdin\n" + ,progname,Output); exit(EXIT_FAILURE); } -#define IS(s) (strcmp(argv[i],s)==0) +#define IS(s) (strcmp(argv[i],s)==0) static int doargs(int argc, char* argv[]) { @@ -89,7 +88,8 @@ static int doargs(int argc, char* argv[]) else if (IS("-o")) /* output file */ { output=argv[++i]; - if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument"); + if (output==NULL || *output==0 || (*output=='-' && output[1]!=0)) + usage(LUA_QL("-o") " needs argument"); if (IS("-")) output=NULL; } else if (IS("-p")) /* parse only */ @@ -108,13 +108,30 @@ static int doargs(int argc, char* argv[]) } if (version) { - printf("%s %s\n",LUA_RELEASE,LUA_COPYRIGHT); + printf("%s\n",LUA_COPYRIGHT); if (version==argc-1) exit(EXIT_SUCCESS); } return i; } -#define toproto(L,i) (clvalue(L->top+(i))->l.p) +#define FUNCTION "(function()end)();" + +static const char* reader(lua_State *L, void *ud, size_t *size) +{ + UNUSED(L); + if ((*(int*)ud)--) + { + *size=sizeof(FUNCTION)-1; + return FUNCTION; + } + else + { + *size=0; + return NULL; + } +} + +#define toproto(L,i) getproto(L->top+(i)) static const Proto* combine(lua_State* L, int n) { @@ -122,24 +139,16 @@ static const Proto* combine(lua_State* L, int n) return toproto(L,-1); else { - int i,pc; - Proto* f=luaF_newproto(L); - setptvalue2s(L,L->top,f); incr_top(L); - f->source=luaS_newliteral(L,"=(" PROGNAME ")"); - f->maxstacksize=1; - pc=2*n+1; - f->code=luaM_newvector(L,pc,Instruction); - f->sizecode=pc; - f->p=luaM_newvector(L,n,Proto*); - f->sizep=n; - pc=0; + Proto* f; + int i=n; + if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1)); + f=toproto(L,-1); for (i=0; ip[i]=toproto(L,i-n-1); - f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); - f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); + if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; } - f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + f->sizelineinfo=0; return f; } } @@ -150,23 +159,17 @@ static int writer(lua_State* L, const void* p, size_t size, void* u) return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); } -struct Smain { - int argc; - char** argv; -}; - static int pmain(lua_State* L) { - struct Smain* s = (struct Smain*)lua_touserdata(L, 1); - int argc=s->argc; - char** argv=s->argv; + int argc=(int)lua_tointeger(L,1); + char** argv=(char**)lua_touserdata(L,2); const Proto* f; int i; if (!lua_checkstack(L,argc)) fatal("too many input files"); for (i=0; i1); @@ -186,15 +189,244 @@ static int pmain(lua_State* L) int main(int argc, char* argv[]) { lua_State* L; - struct Smain s; int i=doargs(argc,argv); argc-=i; argv+=i; if (argc<=0) usage("no input files given"); - L=lua_open(); - if (L==NULL) fatal("not enough memory for state"); - s.argc=argc; - s.argv=argv; - if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); + L=luaL_newstate(); + if (L==NULL) fatal("cannot create state: not enough memory"); + lua_pushcfunction(L,&pmain); + lua_pushinteger(L,argc); + lua_pushlightuserdata(L,argv); + if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1)); lua_close(L); return EXIT_SUCCESS; } + +/* +** $Id: print.c,v 1.68 2011/09/30 10:21:20 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" + +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + printf("%c",'"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") +#define MYK(x) (-1-(x)) + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c); + break; + case iABx: + printf("%d",a); + if (getBMode(o)==OpArgK) printf(" %d",MYK(bx)); + if (getBMode(o)==OpArgU) printf(" %d",bx); + break; + case iAsBx: + printf("%d %d",a,sbx); + break; + case iAx: + printf("%d",MYK(ax)); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s",UPVALNAME(b)); + break; + case OP_GETTABUP: + printf("\t; %s",UPVALNAME(b)); + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABUP: + printf("\t; %s",UPVALNAME(a)); + if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + case OP_TFORLOOP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); + break; + case OP_EXTRAARG: + printf("\t; "); PrintConstant(f,ax); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) ((x==1)?"":"s") +#define S(x) (int)(x),SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=f->source ? getstr(f->source) : "=?"; + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->sizeupvalues)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintDebug(const Proto* f) +{ + int i,n; + n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } + n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + for (i=0; iupvalues[i].instack,f->upvalues[i].idx); + } +} + +static void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) PrintDebug(f); + for (i=0; ip[i],full); +} diff --git a/src/mod/languages/mod_lua/lua/luaconf.h b/src/mod/languages/mod_lua/lua/luaconf.h index ca2849b5b6..df802c9526 100644 --- a/src/mod/languages/mod_lua/lua/luaconf.h +++ b/src/mod/languages/mod_lua/lua/luaconf.h @@ -1,5 +1,5 @@ /* -** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +** $Id: luaconf.h,v 1.176 2013/03/16 21:10:18 roberto Exp $ ** Configuration file for Lua ** See Copyright Notice in lua.h */ @@ -24,30 +24,44 @@ ** CHANGE it (define it) if you want Lua to avoid the use of any ** non-ansi feature or library. */ -#if defined(__STRICT_ANSI__) +#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__) #define LUA_ANSI #endif -#if !defined(LUA_ANSI) && defined(_WIN32) -#define LUA_WIN +#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_WIN /* enable goodies for regular Windows platforms */ #endif +#if defined(LUA_WIN) +#define LUA_DL_DLL +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#endif + + + #if defined(LUA_USE_LINUX) #define LUA_USE_POSIX #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ #define LUA_USE_READLINE /* needs some extra libraries */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ #endif #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX -#define LUA_DL_DYLD /* does not need extra library */ +#define LUA_USE_DLOPEN /* does not need -ldl */ +#define LUA_USE_READLINE /* needs an extra library: -lreadline */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ #endif /* -@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@@ LUA_USE_POSIX includes all functionality listed as X/Open System @* Interfaces Extension (XSI). ** CHANGE it (define it) if your system is XSI compatible. */ @@ -56,20 +70,10 @@ #define LUA_USE_ISATTY #define LUA_USE_POPEN #define LUA_USE_ULONGJMP +#define LUA_USE_GMTIME_R #endif -/* -@@ LUA_PATH and LUA_CPATH are the names of the environment variables that -@* Lua check to set its paths. -@@ LUA_INIT is the name of the environment variable that Lua -@* checks for initialization code. -** CHANGE them if you want different names. -*/ -#define LUA_PATH "LUA_PATH" -#define LUA_CPATH "LUA_CPATH" -#define LUA_INIT "LUA_INIT" - /* @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for @@ -80,7 +84,7 @@ ** hierarchy or if you want to install your libraries in ** non-conventional directories. */ -#if defined(_WIN32) +#if defined(_WIN32) /* { */ /* ** In Windows, any exclamation mark ('!') in the path is replaced by the ** path of the directory of the executable file of the current process. @@ -88,21 +92,23 @@ #define LUA_LDIR "!\\lua\\" #define LUA_CDIR "!\\" #define LUA_PATH_DEFAULT \ - ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua" #define LUA_CPATH_DEFAULT \ - ".\\?.dll;" ".\\?51.dll;" LUA_CDIR"?.dll;" LUA_CDIR"?51.dll;" LUA_CDIR"clibs\\?.dll;" LUA_CDIR"clibs\\?51.dll;" LUA_CDIR"loadall.dll;" LUA_CDIR"clibs\\loadall.dll" + LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" -#else +#else /* }{ */ + +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/" #define LUA_ROOT "/usr/local/" -#define LUA_LDIR LUA_ROOT "share/lua/5.1/" -#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR #define LUA_PATH_DEFAULT \ - "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" #define LUA_CPATH_DEFAULT \ - "./?.so;" "./lib?51.so;" LUA_CDIR"?.so;" LUA_CDIR"lib?51.so;" LUA_CDIR"loadall.so" -#endif + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif /* } */ /* @@ -118,82 +124,67 @@ /* -@@ LUA_PATHSEP is the character that separates templates in a path. -@@ LUA_PATH_MARK is the string that marks the substitution points in a -@* template. -@@ LUA_EXECDIR in a Windows path is replaced by the executable's -@* directory. -@@ LUA_IGMARK is a mark to ignore all before it when bulding the -@* luaopen_ function name. -** CHANGE them if for some reason your system cannot use those -** characters. (E.g., if one of those characters is a common character -** in file/directory names.) Probably you do not need to change them. +@@ LUA_ENV is the name of the variable that holds the current +@@ environment, used to access global names. +** CHANGE it if you do not like this name. */ -#define LUA_PATHSEP ";" -#define LUA_PATH_MARK "?" -#define LUA_EXECDIR "!" -#define LUA_IGMARK "-" - - -/* -@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. -** CHANGE that if ptrdiff_t is not adequate on your machine. (On most -** machines, ptrdiff_t gives a good choice between int or long.) -*/ -#define LUA_INTEGER ptrdiff_t +#define LUA_ENV "_ENV" /* @@ LUA_API is a mark for all core API functions. -@@ LUALIB_API is a mark for all standard library functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. ** CHANGE them if you need to define those functions in some special way. ** For instance, if you want to create one Windows DLL with the core and ** the libraries, you may want to use the following definition (define ** LUA_BUILD_AS_DLL to get it). */ -#if defined(LUA_BUILD_AS_DLL) +#if defined(LUA_BUILD_AS_DLL) /* { */ -#if defined(LUA_CORE) || defined(LUA_LIB) +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ #define LUA_API __declspec(dllexport) -#else +#else /* }{ */ #define LUA_API __declspec(dllimport) -#endif +#endif /* } */ -#else +#else /* }{ */ -#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(HAVE_VISIBILITY) && (defined(LUA_CORE) || defined(LUA_LIB)) -#define LUA_API __attribute__((visibility("default"))) -#else #define LUA_API extern -#endif -#endif + +#endif /* } */ + /* more often than not the libs go together with the core */ #define LUALIB_API LUA_API +#define LUAMOD_API LUALIB_API /* @@ LUAI_FUNC is a mark for all extern functions that are not to be @* exported to outside modules. -@@ LUAI_DATA is a mark for all extern (const) variables that are not to -@* be exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables +@* that are not to be exported to outside modules (LUAI_DDEF for +@* definitions and LUAI_DDEC for declarations). ** CHANGE them if you need to mark them in some special way. Elf/gcc ** (versions 3.2 and later) mark them as "hidden" to optimize access -** when Lua is compiled as a shared library. +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. */ -#if defined(luaall_c) -#define LUAI_FUNC static -#define LUAI_DATA /* empty */ - -#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ - defined(__ELF__) +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ #define LUAI_FUNC __attribute__((visibility("hidden"))) extern -#define LUAI_DATA LUAI_FUNC +#define LUAI_DDEC LUAI_FUNC +#define LUAI_DDEF /* empty */ -#else +#else /* }{ */ #define LUAI_FUNC extern -#define LUAI_DATA extern -#endif +#define LUAI_DDEC extern +#define LUAI_DDEF /* empty */ +#endif /* } */ @@ -213,177 +204,110 @@ #define LUA_IDSIZE 60 +/* +@@ luai_writestring/luai_writeline define how 'print' prints its results. +** They are only used in libraries and the stand-alone program. (The #if +** avoids including 'stdio.h' everywhere.) +*/ +#if defined(LUA_LIB) || defined(lua_c) +#include +#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) +#endif + +/* +@@ luai_writestringerror defines how to print error messages. +** (A format string with one argument is enough for Lua...) +*/ +#define luai_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) + + +/* +@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, +** strings that are internalized. (Cannot be smaller than reserved words +** or tags for metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#define LUAI_MAXSHORTLEN 40 + + + /* ** {================================================================== -** Stand-alone configuration +** Compatibility with previous versions ** =================================================================== */ -#if defined(lua_c) || defined(luaall_c) +/* +@@ LUA_COMPAT_ALL controls all compatibility options. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_ALL) /* { */ /* -@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that -@* is, whether we're running lua interactively). -** CHANGE it if you have a better definition for non-POSIX/non-Windows -** systems. +@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. +** You can replace it with 'table.unpack'. */ -#if defined(LUA_USE_ISATTY) -#include -#define lua_stdin_is_tty() isatty(0) -#elif defined(LUA_WIN) -#include -#include -#define lua_stdin_is_tty() _isatty(_fileno(stdin)) -#else -#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ -#endif +#define LUA_COMPAT_UNPACK + +/* +@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'. +** You can replace it with 'package.searchers'. +*/ +#define LUA_COMPAT_LOADERS + +/* +@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. +** You can call your C function directly (with light C functions). +*/ +#define lua_cpcall(L,f,u) \ + (lua_pushcfunction(L, (f)), \ + lua_pushlightuserdata(L,(u)), \ + lua_pcall(L,1,0,0)) /* -@@ LUA_PROMPT is the default prompt used by stand-alone Lua. -@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. -** CHANGE them if you want different prompts. (You can also change the -** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. +** You can rewrite 'log10(x)' as 'log(x, 10)'. */ -#define LUA_PROMPT "> " -#define LUA_PROMPT2 ">> " - +#define LUA_COMPAT_LOG10 /* -@@ LUA_PROGNAME is the default name for the stand-alone Lua program. -** CHANGE it if your stand-alone interpreter has a different name and -** your system is not able to detect that name automatically. +@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base +** library. You can rewrite 'loadstring(s)' as 'load(s)'. */ -#define LUA_PROGNAME "lua" - +#define LUA_COMPAT_LOADSTRING /* -@@ LUA_MAXINPUT is the maximum length for an input line in the -@* stand-alone interpreter. -** CHANGE it if you need longer lines. +@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. */ -#define LUA_MAXINPUT 512 - +#define LUA_COMPAT_MAXN /* -@@ lua_readline defines how to show a prompt and then read a line from -@* the standard input. -@@ lua_saveline defines how to "save" a read line in a "history". -@@ lua_freeline defines how to free a line read by lua_readline. -** CHANGE them if you want to improve this functionality (e.g., by using -** GNU readline and history facilities). +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. */ -#if defined(LUA_USE_READLINE) -#include -#include -#include -#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) -#define lua_saveline(L,idx) \ - if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ - add_history(lua_tostring(L, idx)); /* add it to history */ -#define lua_freeline(L,b) ((void)L, free(b)) -#else -#define lua_readline(L,b,p) \ - ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ - fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ -#define lua_saveline(L,idx) { (void)L; (void)idx; } -#define lua_freeline(L,b) { (void)L; (void)b; } -#endif +#define lua_strlen(L,i) lua_rawlen(L, (i)) -#endif +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +/* +@@ LUA_COMPAT_MODULE controls compatibility with previous +** module functions 'module' (Lua) and 'luaL_register' (C). +*/ +#define LUA_COMPAT_MODULE + +#endif /* } */ /* }================================================================== */ -/* -@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles -@* as a percentage. -** CHANGE it if you want the GC to run faster or slower (higher values -** mean larger pauses which mean slower collection.) You can also change -** this value dynamically. -*/ -#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ - - -/* -@@ LUAI_GCMUL defines the default speed of garbage collection relative to -@* memory allocation as a percentage. -** CHANGE it if you want to change the granularity of the garbage -** collection. (Higher values mean coarser collections. 0 represents -** infinity, where each step performs a full collection.) You can also -** change this value dynamically. -*/ -#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ - - - -/* -@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. -** CHANGE it (define it) if you want exact compatibility with the -** behavior of setn/getn in Lua 5.0. -*/ -#undef LUA_COMPAT_GETN - -/* -@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. -** CHANGE it to undefined as soon as you do not need a global 'loadlib' -** function (the function is still available as 'package.loadlib'). -*/ -#undef LUA_COMPAT_LOADLIB - -/* -@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. -** CHANGE it to undefined as soon as your programs use only '...' to -** access vararg parameters (instead of the old 'arg' table). -*/ -#define LUA_COMPAT_VARARG - -/* -@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. -** CHANGE it to undefined as soon as your programs use 'math.fmod' or -** the new '%' operator instead of 'math.mod'. -*/ -#define LUA_COMPAT_MOD - -/* -@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting -@* facility. -** CHANGE it to 2 if you want the old behaviour, or undefine it to turn -** off the advisory error when nesting [[...]]. -*/ -#define LUA_COMPAT_LSTR 1 - -/* -@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. -** CHANGE it to undefined as soon as you rename 'string.gfind' to -** 'string.gmatch'. -*/ -#define LUA_COMPAT_GFIND - -/* -@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' -@* behavior. -** CHANGE it to undefined as soon as you replace to 'luaL_register' -** your uses of 'luaL_openlib' -*/ -#define LUA_COMPAT_OPENLIB - - - -/* -@@ luai_apicheck is the assert macro used by the Lua-C API. -** CHANGE luai_apicheck if you want Lua to perform some checks in the -** parameters it gets from API calls. This may slow down the interpreter -** a bit, but may be quite useful when debugging C code that interfaces -** with Lua. A useful redefinition is to use assert.h. -*/ -#if defined(LUA_USE_APICHECK) -#include -#define luai_apicheck(L,o) { (void)L; assert(o); } -#else -#define luai_apicheck(L,o) { (void)L; } -#endif - /* @@ LUAI_BITSINT defines the number of bits in an int. @@ -391,107 +315,62 @@ ** your machine. Probably you do not need to change this. */ /* avoid overflows in comparison */ -#if INT_MAX-20 < 32760 +#if INT_MAX-20 < 32760 /* { */ #define LUAI_BITSINT 16 -#elif INT_MAX > 2147483640L +#elif INT_MAX > 2147483640L /* }{ */ /* int has at least 32 bits */ #define LUAI_BITSINT 32 -#else +#else /* }{ */ #error "you must define LUA_BITSINT with number of bits in an integer" -#endif +#endif /* } */ /* -@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. -@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUA_INT32 is an signed integer with exactly 32 bits. @@ LUAI_UMEM is an unsigned integer big enough to count the total @* memory used by Lua. @@ LUAI_MEM is a signed integer big enough to count the total memory @* used by Lua. ** CHANGE here if for some weird reason the default definitions are not -** good enough for your machine. (The definitions in the 'else' -** part always works, but may waste space on machines with 64-bit -** longs.) Probably you do not need to change this. +** good enough for your machine. Probably you do not need to change +** this. */ -#if LUAI_BITSINT >= 32 -#define LUAI_UINT32 unsigned int -#define LUAI_INT32 int -#define LUAI_MAXINT32 INT_MAX +#if LUAI_BITSINT >= 32 /* { */ +#define LUA_INT32 int #define LUAI_UMEM size_t #define LUAI_MEM ptrdiff_t -#else +#else /* }{ */ /* 16-bit ints */ -#define LUAI_UINT32 unsigned long -#define LUAI_INT32 long -#define LUAI_MAXINT32 LONG_MAX +#define LUA_INT32 long #define LUAI_UMEM unsigned long #define LUAI_MEM long +#endif /* } */ + + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua to consume unlimited stack +** space (and to reserve some numbers for pseudo-indices). +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 #endif - -/* -@@ LUAI_MAXCALLS limits the number of nested calls. -** CHANGE it if you need really deep recursive calls. This limit is -** arbitrary; its only purpose is to stop infinite recursion before -** exhausting memory. -*/ -#define LUAI_MAXCALLS 20000 +/* reserve some space for error handling */ +#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) -/* -@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function -@* can use. -** CHANGE it if you need lots of (Lua) stack space for your C -** functions. This limit is arbitrary; its only purpose is to stop C -** functions to consume unlimited stack space. (must be smaller than -** -LUA_REGISTRYINDEX) -*/ -#define LUAI_MAXCSTACK 8000 - - - -/* -** {================================================================== -** CHANGE (to smaller values) the following definitions if your system -** has a small C stack. (Or you may want to change them to larger -** values if your system has a large C stack and these limits are -** too rigid for you.) Some of these constants control the size of -** stack-allocated arrays used by the compiler or the interpreter, while -** others limit the maximum number of recursive calls that the compiler -** or the interpreter can perform. Values too large may cause a C stack -** overflow for some forms of deep constructs. -** =================================================================== -*/ - - -/* -@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and -@* syntactical nested non-terminals in a program. -*/ -#define LUAI_MAXCCALLS 200 - - -/* -@@ LUAI_MAXVARS is the maximum number of local variables per function -@* (must be smaller than 250). -*/ -#define LUAI_MAXVARS 200 - - -/* -@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function -@* (must be smaller than 250). -*/ -#define LUAI_MAXUPVALUES 60 /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +** CHANGE it if it uses too much C-stack space. */ #define LUAL_BUFFERSIZE BUFSIZ -/* }================================================================== */ - @@ -519,238 +398,144 @@ @@ LUA_NUMBER_FMT is the format for writing numbers. @@ lua_number2str converts a number to a string. @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. -@@ lua_str2number converts a string to a number. */ #define LUA_NUMBER_SCAN "%lf" #define LUA_NUMBER_FMT "%.14g" #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ + + +/* +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations +*/ +#define l_mathop(x) (x) + + +/* +@@ lua_str2number converts a decimal numeric string to a number. +@@ lua_strx2number converts an hexadecimal numeric string to a number. +** In C99, 'strtod' does both conversions. C89, however, has no function +** to convert floating hexadecimal strings to numbers. For these +** systems, you can leave 'lua_strx2number' undefined and Lua will +** provide its own implementation. +*/ #define lua_str2number(s,p) strtod((s), (p)) +#if defined(LUA_USE_STRTODHEX) +#define lua_strx2number(s,p) strtod((s), (p)) +#endif + /* @@ The luai_num* macros define the primitive operations over numbers. */ -#if defined(LUA_CORE) + +/* the following operations need the math library */ +#if defined(lobject_c) || defined(lvm_c) #include -#define luai_numadd(a,b) ((a)+(b)) -#define luai_numsub(a,b) ((a)-(b)) -#define luai_nummul(a,b) ((a)*(b)) -#define luai_numdiv(a,b) ((a)/(b)) -#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) -#define luai_numpow(a,b) (pow(a,b)) -#define luai_numunm(a) (-(a)) -#define luai_numeq(a,b) ((a)==(b)) -#define luai_numlt(a,b) ((a)<(b)) -#define luai_numle(a,b) ((a)<=(b)) -#define luai_numisnan(a) (!luai_numeq((a), (a))) +#define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b)) +#define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) #endif +/* these are quite standard operations */ +#if defined(LUA_CORE) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numdiv(L,a,b) ((a)/(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(L,a,b) ((a)<(b)) +#define luai_numle(L,a,b) ((a)<=(b)) +#define luai_numisnan(L,a) (!luai_numeq((a), (a))) +#endif + + /* -@@ lua_number2int is a macro to convert lua_Number to int. -@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. -** CHANGE them if you know a faster way to convert a lua_Number to -** int (with any rounding method and without throwing errors) in your -** system. In Pentium machines, a naive typecast from double to int -** in C is extremely slow, so any alternative is worth trying. +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + +/* +@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. +** It must have at least 32 bits. +*/ +#define LUA_UNSIGNED unsigned LUA_INT32 + + + +/* +** Some tricks with doubles */ -/* On a Pentium, resort to a trick */ -#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ - (defined(__i386) || defined (_M_IX86) || defined(__i386__)) +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ +/* +** The next definitions activate some tricks to speed up the +** conversion from doubles to integer types, mainly to LUA_UNSIGNED. +** +@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a +** DirectX idiosyncrasy. +** +@@ LUA_IEEE754TRICK uses a trick that should work on any machine +** using IEEE754 with a 32-bit integer type. +** +@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be +** defined when LUA_INTEGER is a 32-bit integer. +** +@@ LUA_IEEEENDIAN is the endianness of doubles in your machine +** (0 for little endian, 1 for big endian); if not defined, Lua will +** check it dynamically for LUA_IEEE754TRICK (but not for LUA_NANTRICK). +** +@@ LUA_NANTRICK controls the use of a trick to pack all types into +** a single double value, using NaN values to represent non-number +** values. The trick only works on 32-bit machines (ints and pointers +** are 32-bit values) with numbers represented as IEEE 754-2008 doubles +** with conventional endianess (12345678 or 87654321), in CPUs that do +** not produce signaling NaN values (all NaNs are quiet). +*/ -/* On a Microsoft compiler, use assembler */ -#if defined(_MSC_VER) +/* Microsoft compiler on a Pentium (32 bit) ? */ +#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ -#define lua_number2int(i,d) __asm fld d __asm fistp i -#define lua_number2integer(i,n) lua_number2int(i, n) - -/* the next trick should work on any Pentium, but sometimes clashes - with a DirectX idiosyncrasy */ -#else - -union luai_Cast { double l_d; long l_l; }; -#define lua_number2int(i,d) \ - { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } -#define lua_number2integer(i,n) lua_number2int(i, n) - -#endif +#define LUA_MSASMTRICK +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK -/* this option always works, but may be slow */ -#else -#define lua_number2int(i,d) ((i)=(int)(d)) -#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) +/* pentium 32 bits? */ +#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ -#endif +#define LUA_IEEE754TRICK +#define LUA_IEEELL +#define LUA_IEEEENDIAN 0 +#define LUA_NANTRICK + +/* pentium 64 bits? */ +#elif defined(__x86_64) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 0 + +#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ + +#define LUA_IEEE754TRICK +#define LUA_IEEEENDIAN 1 + +#else /* }{ */ + +/* assume IEEE754 and a 32-bit integer type */ +#define LUA_IEEE754TRICK + +#endif /* } */ + +#endif /* } */ /* }================================================================== */ -/* -@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. -** CHANGE it if your system requires alignments larger than double. (For -** instance, if your system supports long doubles and they must be -** aligned in 16-byte boundaries, then you should add long double in the -** union.) Probably you do not need to change this. -*/ -#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } - - -/* -@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. -** CHANGE them if you prefer to use longjmp/setjmp even with C++ -** or if want/don't to use _longjmp/_setjmp instead of regular -** longjmp/setjmp. By default, Lua handles errors with exceptions when -** compiling as C++ code, with _longjmp/_setjmp when asked to use them, -** and with longjmp/setjmp otherwise. -*/ -#if defined(__cplusplus) -/* C++ exceptions */ -#define LUAI_THROW(L,c) throw(c) -#define LUAI_TRY(L,c,a) try { a } catch(...) \ - { if ((c)->status == 0) (c)->status = -1; } -#define luai_jmpbuf int /* dummy variable */ - -#elif defined(LUA_USE_ULONGJMP) -/* in Unix, try _longjmp/_setjmp (more efficient) */ -#define LUAI_THROW(L,c) _longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf - -#else -/* default handling with long jumps */ -#define LUAI_THROW(L,c) longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf - -#endif - - -/* -@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern -@* can do during pattern-matching. -** CHANGE it if you need more captures. This limit is arbitrary. -*/ -#define LUA_MAXCAPTURES 32 - - -/* -@@ lua_tmpnam is the function that the OS library uses to create a -@* temporary name. -@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. -** CHANGE them if you have an alternative to tmpnam (which is considered -** insecure) or if you want the original tmpnam anyway. By default, Lua -** uses tmpnam except when POSIX is available, where it uses mkstemp. -*/ -#if defined(loslib_c) || defined(luaall_c) - -#if defined(LUA_USE_MKSTEMP) -#include -#define LUA_TMPNAMBUFSIZE 32 -#define lua_tmpnam(b,e) { \ - strcpy(b, "/tmp/lua_XXXXXX"); \ - e = mkstemp(b); \ - if (e != -1) close(e); \ - e = (e == -1); } - -#else -#define LUA_TMPNAMBUFSIZE L_tmpnam -#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } -#endif - -#endif - - -/* -@@ lua_popen spawns a new process connected to the current one through -@* the file streams. -** CHANGE it if you have a way to implement it in your system. -*/ -#if defined(LUA_USE_POPEN) - -#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) -#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) - -#elif defined(LUA_WIN) - -#define lua_popen(L,c,m) ((void)L, _popen(c,m)) -#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) - -#else - -#define lua_popen(L,c,m) ((void)((void)c, m), \ - luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) -#define lua_pclose(L,file) ((void)((void)L, file), 0) - -#endif - -/* -@@ LUA_DL_* define which dynamic-library system Lua should use. -** CHANGE here if Lua has problems choosing the appropriate -** dynamic-library system for your platform (either Windows' DLL, Mac's -** dyld, or Unix's dlopen). If your system is some kind of Unix, there -** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for -** it. To use dlopen you also need to adapt the src/Makefile (probably -** adding -ldl to the linker options), so Lua does not select it -** automatically. (When you change the makefile to add -ldl, you must -** also add -DLUA_USE_DLOPEN.) -** If you do not want any kind of dynamic library, undefine all these -** options. -** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. -*/ -#if defined(LUA_USE_DLOPEN) -#define LUA_DL_DLOPEN -#endif - -#if defined(LUA_WIN) -#define LUA_DL_DLL -#endif - - -/* -@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State -@* (the data goes just *before* the lua_State pointer). -** CHANGE (define) this if you really need that. This value must be -** a multiple of the maximum alignment required for your machine. -*/ -#define LUAI_EXTRASPACE 0 - - -/* -@@ luai_userstate* allow user-specific actions on threads. -** CHANGE them if you defined LUAI_EXTRASPACE and need to do something -** extra when a thread is created/deleted/resumed/yielded. -*/ -#define luai_userstateopen(L) ((void)L) -#define luai_userstateclose(L) ((void)L) -#define luai_userstatethread(L,L1) ((void)L) -#define luai_userstatefree(L) ((void)L) -#define luai_userstateresume(L,n) ((void)L) -#define luai_userstateyield(L,n) ((void)L) - - -/* -@@ LUA_INTFRMLEN is the length modifier for integer conversions -@* in 'string.format'. -@@ LUA_INTFRM_T is the integer type correspoding to the previous length -@* modifier. -** CHANGE them if your system supports long long or does not support long. -*/ - -#if defined(LUA_USELONGLONG) - -#define LUA_INTFRMLEN "ll" -#define LUA_INTFRM_T long long - -#else - -#define LUA_INTFRMLEN "l" -#define LUA_INTFRM_T long - -#endif - /* =================================================================== */ diff --git a/src/mod/languages/mod_lua/lua/lualib.h b/src/mod/languages/mod_lua/lua/lualib.h index 469417f670..9fd126bf78 100644 --- a/src/mod/languages/mod_lua/lua/lualib.h +++ b/src/mod/languages/mod_lua/lua/lualib.h @@ -1,5 +1,5 @@ /* -** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $ ** Lua standard libraries ** See Copyright Notice in lua.h */ @@ -11,41 +11,43 @@ #include "lua.h" -/* Key to file-handle type */ -#define LUA_FILEHANDLE "FILE*" +LUAMOD_API int (luaopen_base) (lua_State *L); #define LUA_COLIBNAME "coroutine" -LUALIB_API int (luaopen_base) (lua_State *L); +LUAMOD_API int (luaopen_coroutine) (lua_State *L); #define LUA_TABLIBNAME "table" -LUALIB_API int (luaopen_table) (lua_State *L); +LUAMOD_API int (luaopen_table) (lua_State *L); #define LUA_IOLIBNAME "io" -LUALIB_API int (luaopen_io) (lua_State *L); +LUAMOD_API int (luaopen_io) (lua_State *L); #define LUA_OSLIBNAME "os" -LUALIB_API int (luaopen_os) (lua_State *L); +LUAMOD_API int (luaopen_os) (lua_State *L); #define LUA_STRLIBNAME "string" -LUALIB_API int (luaopen_string) (lua_State *L); +LUAMOD_API int (luaopen_string) (lua_State *L); + +#define LUA_BITLIBNAME "bit32" +LUAMOD_API int (luaopen_bit32) (lua_State *L); #define LUA_MATHLIBNAME "math" -LUALIB_API int (luaopen_math) (lua_State *L); +LUAMOD_API int (luaopen_math) (lua_State *L); #define LUA_DBLIBNAME "debug" -LUALIB_API int (luaopen_debug) (lua_State *L); +LUAMOD_API int (luaopen_debug) (lua_State *L); #define LUA_LOADLIBNAME "package" -LUALIB_API int (luaopen_package) (lua_State *L); +LUAMOD_API int (luaopen_package) (lua_State *L); /* open all previous libraries */ -LUALIB_API void (luaL_openlibs) (lua_State *L); +LUALIB_API void (luaL_openlibs) (lua_State *L); -#ifndef lua_assert +#if !defined(lua_assert) #define lua_assert(x) ((void)0) #endif diff --git a/src/mod/languages/mod_lua/lua/lundump.c b/src/mod/languages/mod_lua/lua/lundump.c index 8010a45795..54de011a45 100644 --- a/src/mod/languages/mod_lua/lua/lundump.c +++ b/src/mod/languages/mod_lua/lua/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ +** $Id: lundump.c,v 2.22 2012/05/08 13:53:33 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -27,28 +27,24 @@ typedef struct { const char* name; } LoadState; -#ifdef LUAC_TRUST_BINARIES -#define IF(c,s) -#define error(S,s) -#else -#define IF(c,s) if (c) error(S,s) - -static void error(LoadState* S, const char* why) +static l_noret error(LoadState* S, const char* why) { - luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); + luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); luaD_throw(S->L,LUA_ERRSYNTAX); } -#endif #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) -#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadByte(S) (lu_byte)LoadChar(S) #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) +#if !defined(luai_verifycode) +#define luai_verifycode(L,b,f) /* empty */ +#endif + static void LoadBlock(LoadState* S, void* b, size_t size) { - size_t r=luaZ_read(S->Z,b,size); - IF (r!=0, "unexpected end"); + if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); } static int LoadChar(LoadState* S) @@ -62,7 +58,7 @@ static int LoadInt(LoadState* S) { int x; LoadVar(S,x); - IF (x<0, "bad integer"); + if (x<0) error(S,"corrupted"); return x; } @@ -82,7 +78,7 @@ static TString* LoadString(LoadState* S) else { char* s=luaZ_openspace(S->L,S->b,size); - LoadBlock(S,s,size); + LoadBlock(S,s,size*sizeof(char)); return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ } } @@ -95,7 +91,7 @@ static void LoadCode(LoadState* S, Proto* f) LoadVector(S,f->code,n,sizeof(Instruction)); } -static Proto* LoadFunction(LoadState* S, TString* p); +static void LoadFunction(LoadState* S, Proto* f); static void LoadConstants(LoadState* S, Proto* f) { @@ -111,10 +107,10 @@ static void LoadConstants(LoadState* S, Proto* f) switch (t) { case LUA_TNIL: - setnilvalue(o); + setnilvalue(o); break; case LUA_TBOOLEAN: - setbvalue(o,LoadChar(S)!=0); + setbvalue(o,LoadChar(S)); break; case LUA_TNUMBER: setnvalue(o,LoadNumber(S)); @@ -122,21 +118,38 @@ static void LoadConstants(LoadState* S, Proto* f) case LUA_TSTRING: setsvalue2n(S->L,o,LoadString(S)); break; - default: - error(S,"bad constant"); - break; + default: lua_assert(0); } } n=LoadInt(S); f->p=luaM_newvector(S->L,n,Proto*); f->sizep=n; for (i=0; ip[i]=NULL; - for (i=0; ip[i]=LoadFunction(S,f->source); + for (i=0; ip[i]=luaF_newproto(S->L); + LoadFunction(S,f->p[i]); + } +} + +static void LoadUpvalues(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,Upvaldesc); + f->sizeupvalues=n; + for (i=0; iupvalues[i].name=NULL; + for (i=0; iupvalues[i].instack=LoadByte(S); + f->upvalues[i].idx=LoadByte(S); + } } static void LoadDebug(LoadState* S, Proto* f) { int i,n; + f->source=LoadString(S); n=LoadInt(S); f->lineinfo=luaM_newvector(S->L,n,int); f->sizelineinfo=n; @@ -152,49 +165,48 @@ static void LoadDebug(LoadState* S, Proto* f) f->locvars[i].endpc=LoadInt(S); } n=LoadInt(S); - f->upvalues=luaM_newvector(S->L,n,TString*); - f->sizeupvalues=n; - for (i=0; iupvalues[i]=NULL; - for (i=0; iupvalues[i]=LoadString(S); + for (i=0; iupvalues[i].name=LoadString(S); } -static Proto* LoadFunction(LoadState* S, TString* p) +static void LoadFunction(LoadState* S, Proto* f) { - Proto* f; - if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); - f=luaF_newproto(S->L); - setptvalue2s(S->L,S->L->top,f); incr_top(S->L); - f->source=LoadString(S); if (f->source==NULL) f->source=p; f->linedefined=LoadInt(S); f->lastlinedefined=LoadInt(S); - f->nups=LoadByte(S); f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); f->maxstacksize=LoadByte(S); LoadCode(S,f); LoadConstants(S,f); + LoadUpvalues(S,f); LoadDebug(S,f); - IF (!luaG_checkcode(f), "bad code"); - S->L->top--; - S->L->nCcalls--; - return f; } +/* the code below must be consistent with the code in luaU_header */ +#define N0 LUAC_HEADERSIZE +#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) +#define N2 N1+2 +#define N3 N2+6 + static void LoadHeader(LoadState* S) { - char h[LUAC_HEADERSIZE]; - char s[LUAC_HEADERSIZE]; + lu_byte h[LUAC_HEADERSIZE]; + lu_byte s[LUAC_HEADERSIZE]; luaU_header(h); - LoadBlock(S,s,LUAC_HEADERSIZE); - IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); + memcpy(s,h,sizeof(char)); /* first char already read */ + LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); + if (memcmp(h,s,N0)==0) return; + if (memcmp(h,s,N1)!=0) error(S,"not a"); + if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); + if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); } /* ** load precompiled chunk */ -Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) { LoadState S; + Closure* cl; if (*name=='@' || *name=='=') S.name=name+1; else if (*name==LUA_SIGNATURE[0]) @@ -205,23 +217,42 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) S.Z=Z; S.b=buff; LoadHeader(&S); - return LoadFunction(&S,luaS_newliteral(L,"=?")); + cl=luaF_newLclosure(L,1); + setclLvalue(L,L->top,cl); incr_top(L); + cl->l.p=luaF_newproto(L); + LoadFunction(&S,cl->l.p); + if (cl->l.p->sizeupvalues != 1) + { + Proto* p=cl->l.p; + cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); + cl->l.p=p; + setclLvalue(L,L->top-1,cl); + } + luai_verifycode(L,buff,cl->l.p); + return cl; } +#define MYINT(s) (s[0]-'0') +#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) +#define FORMAT 0 /* this is the official format */ + /* -* make header +* make header for precompiled chunks +* if you change the code below be sure to update LoadHeader and FORMAT above +* and LUAC_HEADERSIZE in lundump.h */ -void luaU_header (char* h) +void luaU_header (lu_byte* h) { int x=1; - memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); - h+=sizeof(LUA_SIGNATURE)-1; - *h++=(char)LUAC_VERSION; - *h++=(char)LUAC_FORMAT; - *h++=(char)*(char*)&x; /* endianness */ - *h++=(char)sizeof(int); - *h++=(char)sizeof(size_t); - *h++=(char)sizeof(Instruction); - *h++=(char)sizeof(lua_Number); - *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); + h+=sizeof(LUA_SIGNATURE)-sizeof(char); + *h++=cast_byte(VERSION); + *h++=cast_byte(FORMAT); + *h++=cast_byte(*(char*)&x); /* endianness */ + *h++=cast_byte(sizeof(int)); + *h++=cast_byte(sizeof(size_t)); + *h++=cast_byte(sizeof(Instruction)); + *h++=cast_byte(sizeof(lua_Number)); + *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ + memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); } diff --git a/src/mod/languages/mod_lua/lua/lundump.h b/src/mod/languages/mod_lua/lua/lundump.h index c80189dbff..2b8accecb8 100644 --- a/src/mod/languages/mod_lua/lua/lundump.h +++ b/src/mod/languages/mod_lua/lua/lundump.h @@ -1,5 +1,5 @@ /* -** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lundump.h,v 1.39 2012/05/08 13:53:33 roberto Exp $ ** load precompiled Lua chunks ** See Copyright Notice in lua.h */ @@ -11,26 +11,18 @@ #include "lzio.h" /* load one chunk; from lundump.c */ -LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); +LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); /* make header; from lundump.c */ -LUAI_FUNC void luaU_header (char* h); +LUAI_FUNC void luaU_header (lu_byte* h); /* dump one chunk; from ldump.c */ LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); -#ifdef luac_c -/* print one chunk; from print.c */ -LUAI_FUNC void luaU_print (const Proto* f, int full); -#endif +/* data to catch conversion errors */ +#define LUAC_TAIL "\x19\x93\r\n\x1a\n" -/* for header of binary files -- this is Lua 5.1 */ -#define LUAC_VERSION 0x51 - -/* for header of binary files -- this is the official format */ -#define LUAC_FORMAT 0 - -/* size of header of binary files */ -#define LUAC_HEADERSIZE 12 +/* size in bytes of header of binary files */ +#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) #endif diff --git a/src/mod/languages/mod_lua/lua/lvm.c b/src/mod/languages/mod_lua/lua/lvm.c index ee3256ab94..657d5c456a 100644 --- a/src/mod/languages/mod_lua/lua/lvm.c +++ b/src/mod/languages/mod_lua/lua/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ +** $Id: lvm.c,v 2.155 2013/03/16 21:10:18 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -35,7 +35,7 @@ const TValue *luaV_tonumber (const TValue *obj, TValue *n) { lua_Number num; if (ttisnumber(obj)) return obj; - if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { + if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { setnvalue(n, num); return n; } @@ -50,58 +50,60 @@ int luaV_tostring (lua_State *L, StkId obj) { else { char s[LUAI_MAXNUMBER2STR]; lua_Number n = nvalue(obj); - lua_number2str(s, n); - setsvalue2s(L, obj, luaS_new(L, s)); + int l = lua_number2str(s, n); + setsvalue2s(L, obj, luaS_newlstr(L, s, l)); return 1; } } -static void traceexec (lua_State *L, const Instruction *pc) { +static void traceexec (lua_State *L) { + CallInfo *ci = L->ci; lu_byte mask = L->hookmask; - const Instruction *oldpc = L->savedpc; - L->savedpc = pc; - if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { - resethookcount(L); - luaD_callhook(L, LUA_HOOKCOUNT, -1); + int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); + if (counthook) + resethookcount(L); /* reset count */ + if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ + ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ + return; /* do not call hook again (VM yielded, so it did not move) */ } + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ if (mask & LUA_MASKLINE) { - Proto *p = ci_func(L->ci)->l.p; - int npc = pcRel(pc, p); - int newline = getline(p, npc); - /* call linehook when enter a new function, when jump back (loop), - or when enter a new line */ - if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) - luaD_callhook(L, LUA_HOOKLINE, newline); + Proto *p = ci_func(ci)->p; + int npc = pcRel(ci->u.l.savedpc, p); + int newline = getfuncline(p, npc); + if (npc == 0 || /* call linehook when enter a new function, */ + ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ + newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ + luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ + } + L->oldpc = ci->u.l.savedpc; + if (L->status == LUA_YIELD) { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ + ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ + ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ + ci->func = L->top - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); } } -static void callTMres (lua_State *L, StkId res, const TValue *f, - const TValue *p1, const TValue *p2) { - ptrdiff_t result = savestack(L, res); - setobj2s(L, L->top, f); /* push function */ - setobj2s(L, L->top+1, p1); /* 1st argument */ - setobj2s(L, L->top+2, p2); /* 2nd argument */ - luaD_checkstack(L, 3); - L->top += 3; - luaD_call(L, L->top - 3, 1); - res = restorestack(L, result); - L->top--; - setobjs2s(L, res, L->top); -} - - - static void callTM (lua_State *L, const TValue *f, const TValue *p1, - const TValue *p2, const TValue *p3) { - setobj2s(L, L->top, f); /* push function */ - setobj2s(L, L->top+1, p1); /* 1st argument */ - setobj2s(L, L->top+2, p2); /* 2nd argument */ - setobj2s(L, L->top+3, p3); /* 3th argument */ - luaD_checkstack(L, 4); - L->top += 4; - luaD_call(L, L->top - 4, 0); + const TValue *p2, TValue *p3, int hasres) { + ptrdiff_t result = savestack(L, p3); + setobj2s(L, L->top++, f); /* push function */ + setobj2s(L, L->top++, p1); /* 1st argument */ + setobj2s(L, L->top++, p2); /* 2nd argument */ + if (!hasres) /* no result? 'p3' is third argument */ + setobj2s(L, L->top++, p3); /* 3rd argument */ + /* metamethod may yield only when called from Lua code */ + luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); + if (hasres) { /* if has result, move it to its place */ + p3 = restorestack(L, result); + setobjs2s(L, p3, --L->top); + } } @@ -112,7 +114,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { if (ttistable(t)) { /* `t' is a table? */ Table *h = hvalue(t); const TValue *res = luaH_get(h, key); /* do a primitive get */ - if (!ttisnil(res) || /* result is no nil? */ + if (!ttisnil(res) || /* result is not nil? */ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ setobj2s(L, val, res); return; @@ -122,10 +124,10 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm)) { - callTMres(L, val, tm, t, key); + callTM(L, tm, t, key, val, 1); return; } - t = tm; /* else repeat with `tm' */ + t = tm; /* else repeat with 'tm' */ } luaG_runerror(L, "loop in gettable"); } @@ -137,22 +139,34 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { const TValue *tm; if (ttistable(t)) { /* `t' is a table? */ Table *h = hvalue(t); - TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ - if (!ttisnil(oldval) || /* result is no nil? */ - (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ - setobj2t(L, oldval, val); - luaC_barriert(L, h, val); + TValue *oldval = cast(TValue *, luaH_get(h, key)); + /* if previous value is not nil, there must be a previous entry + in the table; moreover, a metamethod has no relevance */ + if (!ttisnil(oldval) || + /* previous value is nil; must check the metamethod */ + ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && + /* no metamethod; is there a previous entry in the table? */ + (oldval != luaO_nilobject || + /* no previous entry; must create one. (The next test is + always true; we only need the assignment.) */ + (oldval = luaH_newkey(L, h, key), 1)))) { + /* no metamethod and (now) there is an entry with given key */ + setobj2t(L, oldval, val); /* assign new value to that entry */ + invalidateTMcache(h); + luaC_barrierback(L, obj2gco(h), val); return; } - /* else will try the tag method */ + /* else will try the metamethod */ } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) - luaG_typeerror(L, t, "index"); + else /* not a table; check metamethod */ + if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + /* there is a metamethod */ if (ttisfunction(tm)) { - callTM(L, tm, t, key, val); + callTM(L, tm, t, key, val, 0); return; } - t = tm; /* else repeat with `tm' */ + t = tm; /* else repeat with 'tm' */ } luaG_runerror(L, "loop in settable"); } @@ -164,12 +178,12 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, if (ttisnil(tm)) tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ if (ttisnil(tm)) return 0; - callTMres(L, res, tm, p1, p2); + callTM(L, tm, p1, p2, res, 1); return 1; } -static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, +static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, TMS event) { const TValue *tm1 = fasttm(L, mt1, event); const TValue *tm2; @@ -177,7 +191,7 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ tm2 = fasttm(L, mt2, event); if (tm2 == NULL) return NULL; /* no metamethod */ - if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ return tm1; return NULL; } @@ -185,14 +199,10 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, TMS event) { - const TValue *tm1 = luaT_gettmbyobj(L, p1, event); - const TValue *tm2; - if (ttisnil(tm1)) return -1; /* no metamethod? */ - tm2 = luaT_gettmbyobj(L, p2, event); - if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ - return -1; - callTMres(L, L->top, tm1, p1, p2); - return !l_isfalse(L->top); + if (!call_binTM(L, p1, p2, L->top, event)) + return -1; /* no metamethod */ + else + return !l_isfalse(L->top); } @@ -220,125 +230,261 @@ static int l_strcmp (const TString *ls, const TString *rs) { int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { int res; - if (ttype(l) != ttype(r)) - return luaG_ordererror(L, l, r); - else if (ttisnumber(l)) - return luai_numlt(nvalue(l), nvalue(r)); - else if (ttisstring(l)) + if (ttisnumber(l) && ttisnumber(r)) + return luai_numlt(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; - else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) - return res; - return luaG_ordererror(L, l, r); + else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) + luaG_ordererror(L, l, r); + return res; } -static int lessequal (lua_State *L, const TValue *l, const TValue *r) { +int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { int res; - if (ttype(l) != ttype(r)) - return luaG_ordererror(L, l, r); - else if (ttisnumber(l)) - return luai_numle(nvalue(l), nvalue(r)); - else if (ttisstring(l)) + if (ttisnumber(l) && ttisnumber(r)) + return luai_numle(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; - else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ return res; - else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ - return !res; - return luaG_ordererror(L, l, r); + else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ + luaG_ordererror(L, l, r); + return !res; } -int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { +/* +** equality of Lua values. L == NULL means raw equality (no metamethods) +*/ +int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { const TValue *tm; - lua_assert(ttype(t1) == ttype(t2)); + lua_assert(ttisequal(t1, t2)); switch (ttype(t1)) { case LUA_TNIL: return 1; case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TLCF: return fvalue(t1) == fvalue(t2); + case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); + case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); case LUA_TUSERDATA: { if (uvalue(t1) == uvalue(t2)) return 1; - tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, - TM_EQ); + else if (L == NULL) return 0; + tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); break; /* will try TM */ } case LUA_TTABLE: { if (hvalue(t1) == hvalue(t2)) return 1; - tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + else if (L == NULL) return 0; + tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); break; /* will try TM */ } - default: return gcvalue(t1) == gcvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); } if (tm == NULL) return 0; /* no TM? */ - callTMres(L, L->top, tm, t1, t2); /* call TM */ + callTM(L, tm, t1, t2, L->top, 1); /* call TM */ return !l_isfalse(L->top); } -void luaV_concat (lua_State *L, int total, int last) { +void luaV_concat (lua_State *L, int total) { + lua_assert(total >= 2); do { - StkId top = L->base + last + 1; + StkId top = L->top; int n = 2; /* number of elements handled in this pass (at least 2) */ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) luaG_concaterror(L, top-2, top-1); - } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ - (void)tostring(L, top - 2); /* result is first op (as string) */ + } + else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ + (void)tostring(L, top - 2); /* result is first operand */ + else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { + setobjs2s(L, top - 2, top - 1); /* result is second op. */ + } else { - /* at least two string values; get as many as possible */ + /* at least two non-empty string values; get as many as possible */ size_t tl = tsvalue(top-1)->len; char *buffer; int i; /* collect total length */ - for (n = 1; n < total && tostring(L, top-n-1); n++) { - size_t l = tsvalue(top-n-1)->len; - if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); + for (i = 1; i < total && tostring(L, top-i-1); i++) { + size_t l = tsvalue(top-i-1)->len; + if (l >= (MAX_SIZET/sizeof(char)) - tl) + luaG_runerror(L, "string length overflow"); tl += l; } buffer = luaZ_openspace(L, &G(L)->buff, tl); tl = 0; - for (i=n; i>0; i--) { /* concat all strings */ + n = i; + do { /* concat all strings */ size_t l = tsvalue(top-i)->len; - memcpy(buffer+tl, svalue(top-i), l); + memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); tl += l; - } + } while (--i > 0); setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); } - total -= n-1; /* got `n' strings to create 1 new */ - last -= n-1; + total -= n-1; /* got 'n' strings to create 1 new */ + L->top -= n-1; /* popped 'n' strings and pushed one */ } while (total > 1); /* repeat until only 1 result left */ } -static void Arith (lua_State *L, StkId ra, const TValue *rb, - const TValue *rc, TMS op) { +void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { + const TValue *tm; + switch (ttypenv(rb)) { + case LUA_TTABLE: { + Table *h = hvalue(rb); + tm = fasttm(L, h->metatable, TM_LEN); + if (tm) break; /* metamethod? break switch to call it */ + setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ + return; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + return; + } + default: { /* try metamethod */ + tm = luaT_gettmbyobj(L, rb, TM_LEN); + if (ttisnil(tm)) /* no metamethod? */ + luaG_typeerror(L, rb, "get length of"); + break; + } + } + callTM(L, tm, rb, rb, ra, 1); +} + + +void luaV_arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { TValue tempb, tempc; const TValue *b, *c; if ((b = luaV_tonumber(rb, &tempb)) != NULL && (c = luaV_tonumber(rc, &tempc)) != NULL) { - lua_Number nb = nvalue(b), nc = nvalue(c); - switch (op) { - case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; - case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; - case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; - case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; - case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; - case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; - case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; - default: lua_assert(0); break; - } + lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); + setnvalue(ra, res); } else if (!call_binTM(L, rb, rc, ra, op)) luaG_aritherror(L, rb, rc); } +/* +** check whether cached closure in prototype 'p' may be reused, that is, +** whether there is a cached closure with the same upvalues needed by +** new closure to be created. +*/ +static Closure *getcached (Proto *p, UpVal **encup, StkId base) { + Closure *c = p->cache; + if (c != NULL) { /* is there a cached closure? */ + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ + TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; + if (c->l.upvals[i]->v != v) + return NULL; /* wrong upvalue; cannot reuse closure */ + } + } + return c; /* return cached closure (or NULL if no cached closure) */ +} + + +/* +** create a new Lua closure, push it in the stack, and initialize +** its upvalues. Note that the call to 'luaC_barrierproto' must come +** before the assignment to 'p->cache', as the function needs the +** original value of that field. +*/ +static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, + StkId ra) { + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + Closure *ncl = luaF_newLclosure(L, nup); + ncl->l.p = p; + setclLvalue(L, ra, ncl); /* anchor new closure in stack */ + for (i = 0; i < nup; i++) { /* fill in its upvalues */ + if (uv[i].instack) /* upvalue refers to local variable? */ + ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); + else /* get upvalue from enclosing function */ + ncl->l.upvals[i] = encup[uv[i].idx]; + } + luaC_barrierproto(L, p, ncl); + p->cache = ncl; /* save it on cache for reuse */ +} + + +/* +** finish execution of an opcode interrupted by an yield +*/ +void luaV_finishOp (lua_State *L) { + CallInfo *ci = L->ci; + StkId base = ci->u.l.base; + Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ + OpCode op = GET_OPCODE(inst); + switch (op) { /* finish its execution */ + case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: + case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: + case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { + setobjs2s(L, base + GETARG_A(inst), --L->top); + break; + } + case OP_LE: case OP_LT: case OP_EQ: { + int res = !l_isfalse(L->top - 1); + L->top--; + /* metamethod should not be called when operand is K */ + lua_assert(!ISK(GETARG_B(inst))); + if (op == OP_LE && /* "<=" using "<" instead? */ + ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) + res = !res; /* invert result */ + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); + if (res != GETARG_A(inst)) /* condition failed? */ + ci->u.l.savedpc++; /* skip jump instruction */ + break; + } + case OP_CONCAT: { + StkId top = L->top - 1; /* top when 'call_binTM' was called */ + int b = GETARG_B(inst); /* first element to concatenate */ + int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ + setobj2s(L, top - 2, top); /* put TM result in proper position */ + if (total > 1) { /* are there elements to concat? */ + L->top = top - 1; /* top is one after last element (at top-2) */ + luaV_concat(L, total); /* concat them (may yield again) */ + } + /* move final result to final position */ + setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); + L->top = ci->top; /* restore top */ + break; + } + case OP_TFORCALL: { + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); + L->top = ci->top; /* correct top */ + break; + } + case OP_CALL: { + if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ + L->top = ci->top; /* adjust results */ + break; + } + case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: + break; + default: lua_assert(0); + } +} + + /* ** some macros for common tasks in `luaV_execute' */ -#define runtime_check(L, c) { if (!(c)) break; } +#if !defined luai_runtimecheck +#define luai_runtimecheck(L, c) /* void */ +#endif + #define RA(i) (base+GETARG_A(i)) /* to be used after possible stack reallocation */ @@ -348,13 +494,27 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) -#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) +#define KBx(i) \ + (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) -#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} +/* execute a jump instruction */ +#define dojump(ci,i,e) \ + { int a = GETARG_A(i); \ + if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ + ci->u.l.savedpc += GETARG_sBx(i) + e; } + +/* for test instructions, execute the jump instruction that follows it */ +#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } -#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } +#define Protect(x) { {x;}; base = ci->u.l.base; } + +#define checkGC(L,c) \ + Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \ + luaC_step(L); \ + L->top = ci->top;}) /* restore top */ \ + luai_threadyield(L); ) #define arith_op(op,tm) { \ @@ -362,401 +522,345 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, TValue *rc = RKC(i); \ if (ttisnumber(rb) && ttisnumber(rc)) { \ lua_Number nb = nvalue(rb), nc = nvalue(rc); \ - setnvalue(ra, op(nb, nc)); \ + setnvalue(ra, op(L, nb, nc)); \ } \ - else \ - Protect(Arith(L, ra, rb, rc, tm)); \ - } + else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } +#define vmdispatch(o) switch(o) +#define vmcase(l,b) case l: {b} break; +#define vmcasenb(l,b) case l: {b} /* nb = no break */ -void luaV_execute (lua_State *L, int nexeccalls) { +void luaV_execute (lua_State *L) { + CallInfo *ci = L->ci; LClosure *cl; - StkId base; TValue *k; - const Instruction *pc; - reentry: /* entry point */ - lua_assert(isLua(L->ci)); - pc = L->savedpc; - cl = &clvalue(L->ci->func)->l; - base = L->base; + StkId base; + newframe: /* reentry point when frame changes (call/return) */ + lua_assert(ci == L->ci); + cl = clLvalue(ci->func); k = cl->p->k; + base = ci->u.l.base; /* main loop of interpreter */ for (;;) { - const Instruction i = *pc++; + Instruction i = *(ci->u.l.savedpc++); StkId ra; if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { - traceexec(L, pc); - if (L->status == LUA_YIELD) { /* did hook yield? */ - L->savedpc = pc - 1; - return; - } - base = L->base; + Protect(traceexec(L)); } - /* warning!! several calls may realloc the stack and invalidate `ra' */ + /* WARNING: several calls may realloc the stack and invalidate `ra' */ ra = RA(i); - lua_assert(base == L->base && L->base == L->ci->base); - lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); - lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); - switch (GET_OPCODE(i)) { - case OP_MOVE: { + lua_assert(base == ci->u.l.base); + lua_assert(base <= L->top && L->top < L->stack + L->stacksize); + vmdispatch (GET_OPCODE(i)) { + vmcase(OP_MOVE, setobjs2s(L, ra, RB(i)); - continue; - } - case OP_LOADK: { - setobj2s(L, ra, KBx(i)); - continue; - } - case OP_LOADBOOL: { + ) + vmcase(OP_LOADK, + TValue *rb = k + GETARG_Bx(i); + setobj2s(L, ra, rb); + ) + vmcase(OP_LOADKX, + TValue *rb; + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); + rb = k + GETARG_Ax(*ci->u.l.savedpc++); + setobj2s(L, ra, rb); + ) + vmcase(OP_LOADBOOL, setbvalue(ra, GETARG_B(i)); - if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ - continue; - } - case OP_LOADNIL: { - TValue *rb = RB(i); + if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ + ) + vmcase(OP_LOADNIL, + int b = GETARG_B(i); do { - setnilvalue(rb--); - } while (rb >= ra); - continue; - } - case OP_GETUPVAL: { + setnilvalue(ra++); + } while (b--); + ) + vmcase(OP_GETUPVAL, int b = GETARG_B(i); setobj2s(L, ra, cl->upvals[b]->v); - continue; - } - case OP_GETGLOBAL: { - TValue g; - TValue *rb = KBx(i); - sethvalue(L, &g, cl->env); - lua_assert(ttisstring(rb)); - Protect(luaV_gettable(L, &g, rb, ra)); - continue; - } - case OP_GETTABLE: { + ) + vmcase(OP_GETTABUP, + int b = GETARG_B(i); + Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); + ) + vmcase(OP_GETTABLE, Protect(luaV_gettable(L, RB(i), RKC(i), ra)); - continue; - } - case OP_SETGLOBAL: { - TValue g; - sethvalue(L, &g, cl->env); - lua_assert(ttisstring(KBx(i))); - Protect(luaV_settable(L, &g, KBx(i), ra)); - continue; - } - case OP_SETUPVAL: { + ) + vmcase(OP_SETTABUP, + int a = GETARG_A(i); + Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); + ) + vmcase(OP_SETUPVAL, UpVal *uv = cl->upvals[GETARG_B(i)]; setobj(L, uv->v, ra); luaC_barrier(L, uv, ra); - continue; - } - case OP_SETTABLE: { + ) + vmcase(OP_SETTABLE, Protect(luaV_settable(L, ra, RKB(i), RKC(i))); - continue; - } - case OP_NEWTABLE: { + ) + vmcase(OP_NEWTABLE, int b = GETARG_B(i); int c = GETARG_C(i); - sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); - Protect(luaC_checkGC(L)); - continue; - } - case OP_SELF: { + Table *t = luaH_new(L); + sethvalue(L, ra, t); + if (b != 0 || c != 0) + luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); + checkGC(L, ra + 1); + ) + vmcase(OP_SELF, StkId rb = RB(i); setobjs2s(L, ra+1, rb); Protect(luaV_gettable(L, rb, RKC(i), ra)); - continue; - } - case OP_ADD: { + ) + vmcase(OP_ADD, arith_op(luai_numadd, TM_ADD); - continue; - } - case OP_SUB: { + ) + vmcase(OP_SUB, arith_op(luai_numsub, TM_SUB); - continue; - } - case OP_MUL: { + ) + vmcase(OP_MUL, arith_op(luai_nummul, TM_MUL); - continue; - } - case OP_DIV: { + ) + vmcase(OP_DIV, arith_op(luai_numdiv, TM_DIV); - continue; - } - case OP_MOD: { + ) + vmcase(OP_MOD, arith_op(luai_nummod, TM_MOD); - continue; - } - case OP_POW: { + ) + vmcase(OP_POW, arith_op(luai_numpow, TM_POW); - continue; - } - case OP_UNM: { + ) + vmcase(OP_UNM, TValue *rb = RB(i); if (ttisnumber(rb)) { lua_Number nb = nvalue(rb); - setnvalue(ra, luai_numunm(nb)); + setnvalue(ra, luai_numunm(L, nb)); } else { - Protect(Arith(L, ra, rb, rb, TM_UNM)); + Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); } - continue; - } - case OP_NOT: { - int res = l_isfalse(RB(i)); /* next assignment may change this value */ + ) + vmcase(OP_NOT, + TValue *rb = RB(i); + int res = l_isfalse(rb); /* next assignment may change this value */ setbvalue(ra, res); - continue; - } - case OP_LEN: { - const TValue *rb = RB(i); - switch (ttype(rb)) { - case LUA_TTABLE: { - setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); - break; - } - case LUA_TSTRING: { - setnvalue(ra, cast_num(tsvalue(rb)->len)); - break; - } - default: { /* try metamethod */ - Protect( - if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) - luaG_typeerror(L, rb, "get length of"); - ) - } - } - continue; - } - case OP_CONCAT: { + ) + vmcase(OP_LEN, + Protect(luaV_objlen(L, ra, RB(i))); + ) + vmcase(OP_CONCAT, int b = GETARG_B(i); int c = GETARG_C(i); - Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); - setobjs2s(L, RA(i), base+b); - continue; - } - case OP_JMP: { - dojump(L, pc, GETARG_sBx(i)); - continue; - } - case OP_EQ: { + StkId rb; + L->top = base + c + 1; /* mark the end of concat operands */ + Protect(luaV_concat(L, c - b + 1)); + ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ + rb = b + base; + setobjs2s(L, ra, rb); + checkGC(L, (ra >= rb ? ra + 1 : rb)); + L->top = ci->top; /* restore top */ + ) + vmcase(OP_JMP, + dojump(ci, i, 0); + ) + vmcase(OP_EQ, TValue *rb = RKB(i); TValue *rc = RKC(i); Protect( - if (equalobj(L, rb, rc) == GETARG_A(i)) - dojump(L, pc, GETARG_sBx(*pc)); + if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); ) - pc++; - continue; - } - case OP_LT: { + ) + vmcase(OP_LT, Protect( - if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) - dojump(L, pc, GETARG_sBx(*pc)); + if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); ) - pc++; - continue; - } - case OP_LE: { + ) + vmcase(OP_LE, Protect( - if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) - dojump(L, pc, GETARG_sBx(*pc)); + if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) + ci->u.l.savedpc++; + else + donextjump(ci); ) - pc++; - continue; - } - case OP_TEST: { - if (l_isfalse(ra) != GETARG_C(i)) - dojump(L, pc, GETARG_sBx(*pc)); - pc++; - continue; - } - case OP_TESTSET: { + ) + vmcase(OP_TEST, + if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) + ci->u.l.savedpc++; + else + donextjump(ci); + ) + vmcase(OP_TESTSET, TValue *rb = RB(i); - if (l_isfalse(rb) != GETARG_C(i)) { + if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) + ci->u.l.savedpc++; + else { setobjs2s(L, ra, rb); - dojump(L, pc, GETARG_sBx(*pc)); + donextjump(ci); } - pc++; - continue; - } - case OP_CALL: { + ) + vmcase(OP_CALL, int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) L->top = ra+b; /* else previous instruction set top */ - L->savedpc = pc; - switch (luaD_precall(L, ra, nresults)) { - case PCRLUA: { - nexeccalls++; - goto reentry; /* restart luaV_execute over new Lua function */ - } - case PCRC: { - /* it was a C function (`precall' called it); adjust results */ - if (nresults >= 0) L->top = L->ci->top; - base = L->base; - continue; - } - default: { - return; /* yield */ - } + if (luaD_precall(L, ra, nresults)) { /* C function? */ + if (nresults >= 0) L->top = ci->top; /* adjust results */ + base = ci->u.l.base; } - } - case OP_TAILCALL: { + else { /* Lua function */ + ci = L->ci; + ci->callstatus |= CIST_REENTRY; + goto newframe; /* restart luaV_execute over new Lua function */ + } + ) + vmcase(OP_TAILCALL, int b = GETARG_B(i); if (b != 0) L->top = ra+b; /* else previous instruction set top */ - L->savedpc = pc; lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); - switch (luaD_precall(L, ra, LUA_MULTRET)) { - case PCRLUA: { - /* tail call: put new frame in place of previous one */ - CallInfo *ci = L->ci - 1; /* previous frame */ - int aux; - StkId func = ci->func; - StkId pfunc = (ci+1)->func; /* previous function index */ - if (L->openupval) luaF_close(L, ci->base); - L->base = ci->base = ci->func + ((ci+1)->base - pfunc); - for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ - setobjs2s(L, func+aux, pfunc+aux); - ci->top = L->top = func+aux; /* correct top */ - lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); - ci->savedpc = L->savedpc; - ci->tailcalls++; /* one more call lost */ - L->ci--; /* remove new frame */ - goto reentry; - } - case PCRC: { /* it was a C function (`precall' called it) */ - base = L->base; - continue; - } - default: { - return; /* yield */ - } + if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ + base = ci->u.l.base; + else { + /* tail call: put called frame (n) in place of caller one (o) */ + CallInfo *nci = L->ci; /* called frame */ + CallInfo *oci = nci->previous; /* caller frame */ + StkId nfunc = nci->func; /* called function */ + StkId ofunc = oci->func; /* caller function */ + /* last stack slot filled by 'precall' */ + StkId lim = nci->u.l.base + getproto(nfunc)->numparams; + int aux; + /* close all upvalues from previous call */ + if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); + /* move new frame into old one */ + for (aux = 0; nfunc + aux < lim; aux++) + setobjs2s(L, ofunc + aux, nfunc + aux); + oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ + oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ + oci->u.l.savedpc = nci->u.l.savedpc; + oci->callstatus |= CIST_TAIL; /* function was tail called */ + ci = L->ci = oci; /* remove new frame */ + lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); + goto newframe; /* restart luaV_execute over new Lua function */ } - } - case OP_RETURN: { + ) + vmcasenb(OP_RETURN, int b = GETARG_B(i); if (b != 0) L->top = ra+b-1; - if (L->openupval) luaF_close(L, base); - L->savedpc = pc; + if (cl->p->sizep > 0) luaF_close(L, base); b = luaD_poscall(L, ra); - if (--nexeccalls == 0) /* was previous function running `here'? */ - return; /* no: return */ - else { /* yes: continue its execution */ - if (b) L->top = L->ci->top; - lua_assert(isLua(L->ci)); - lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); - goto reentry; + if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ + return; /* external invocation: return */ + else { /* invocation via reentry: continue execution */ + ci = L->ci; + if (b) L->top = ci->top; + lua_assert(isLua(ci)); + lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); + goto newframe; /* restart luaV_execute over new Lua function */ } - } - case OP_FORLOOP: { + ) + vmcase(OP_FORLOOP, lua_Number step = nvalue(ra+2); - lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ + lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ lua_Number limit = nvalue(ra+1); - if (luai_numlt(0, step) ? luai_numle(idx, limit) - : luai_numle(limit, idx)) { - dojump(L, pc, GETARG_sBx(i)); /* jump back */ + if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) + : luai_numle(L, limit, idx)) { + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ setnvalue(ra, idx); /* update internal index... */ setnvalue(ra+3, idx); /* ...and external index */ } - continue; - } - case OP_FORPREP: { + ) + vmcase(OP_FORPREP, const TValue *init = ra; const TValue *plimit = ra+1; const TValue *pstep = ra+2; - L->savedpc = pc; /* next steps may throw errors */ if (!tonumber(init, ra)) luaG_runerror(L, LUA_QL("for") " initial value must be a number"); else if (!tonumber(plimit, ra+1)) luaG_runerror(L, LUA_QL("for") " limit must be a number"); else if (!tonumber(pstep, ra+2)) luaG_runerror(L, LUA_QL("for") " step must be a number"); - setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); - dojump(L, pc, GETARG_sBx(i)); - continue; - } - case OP_TFORLOOP: { + setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); + ci->u.l.savedpc += GETARG_sBx(i); + ) + vmcasenb(OP_TFORCALL, StkId cb = ra + 3; /* call base */ setobjs2s(L, cb+2, ra+2); setobjs2s(L, cb+1, ra+1); setobjs2s(L, cb, ra); - L->top = cb+3; /* func. + 2 args (state and index) */ - Protect(luaD_call(L, cb, GETARG_C(i))); - L->top = L->ci->top; - cb = RA(i) + 3; /* previous call may change the stack */ - if (!ttisnil(cb)) { /* continue loop? */ - setobjs2s(L, cb-1, cb); /* save control variable */ - dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + L->top = cb + 3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i), 1)); + L->top = ci->top; + i = *(ci->u.l.savedpc++); /* go to next instruction */ + ra = RA(i); + lua_assert(GET_OPCODE(i) == OP_TFORLOOP); + goto l_tforloop; + ) + vmcase(OP_TFORLOOP, + l_tforloop: + if (!ttisnil(ra + 1)) { /* continue loop? */ + setobjs2s(L, ra, ra + 1); /* save control variable */ + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ } - pc++; - continue; - } - case OP_SETLIST: { + ) + vmcase(OP_SETLIST, int n = GETARG_B(i); int c = GETARG_C(i); int last; Table *h; - if (n == 0) { - n = cast_int(L->top - ra) - 1; - L->top = L->ci->top; + if (n == 0) n = cast_int(L->top - ra) - 1; + if (c == 0) { + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); + c = GETARG_Ax(*ci->u.l.savedpc++); } - if (c == 0) c = cast_int(*pc++); - runtime_check(L, ttistable(ra)); + luai_runtimecheck(L, ttistable(ra)); h = hvalue(ra); last = ((c-1)*LFIELDS_PER_FLUSH) + n; if (last > h->sizearray) /* needs more space? */ - luaH_resizearray(L, h, last); /* pre-alloc it at once */ + luaH_resizearray(L, h, last); /* pre-allocate it at once */ for (; n > 0; n--) { TValue *val = ra+n; - setobj2t(L, luaH_setnum(L, h, last--), val); - luaC_barriert(L, h, val); + luaH_setint(L, h, last--, val); + luaC_barrierback(L, obj2gco(h), val); } - continue; - } - case OP_CLOSE: { - luaF_close(L, ra); - continue; - } - case OP_CLOSURE: { - Proto *p; - Closure *ncl; - int nup, j; - p = cl->p->p[GETARG_Bx(i)]; - nup = p->nups; - ncl = luaF_newLclosure(L, nup, cl->env); - ncl->l.p = p; - for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; - else { - lua_assert(GET_OPCODE(*pc) == OP_MOVE); - ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); - } - } - setclvalue(L, ra, ncl); - Protect(luaC_checkGC(L)); - continue; - } - case OP_VARARG: { + L->top = ci->top; /* correct top (in case of previous open call) */ + ) + vmcase(OP_CLOSURE, + Proto *p = cl->p->p[GETARG_Bx(i)]; + Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ + if (ncl == NULL) /* no match? */ + pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ + else + setclLvalue(L, ra, ncl); /* push cashed closure */ + checkGC(L, ra + 1); + ) + vmcase(OP_VARARG, int b = GETARG_B(i) - 1; int j; - CallInfo *ci = L->ci; - int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; - if (b == LUA_MULTRET) { + int n = cast_int(base - ci->func) - cl->p->numparams - 1; + if (b < 0) { /* B == 0? */ + b = n; /* get all var. arguments */ Protect(luaD_checkstack(L, n)); ra = RA(i); /* previous call may change the stack */ - b = n; L->top = ra + n; } for (j = 0; j < b; j++) { if (j < n) { - setobjs2s(L, ra + j, ci->base - n + j); + setobjs2s(L, ra + j, base - n + j); } else { setnilvalue(ra + j); } } - continue; - } + ) + vmcase(OP_EXTRAARG, + lua_assert(0); + ) } } } diff --git a/src/mod/languages/mod_lua/lua/lvm.h b/src/mod/languages/mod_lua/lua/lvm.h index bfe4f5678d..07e25f9c64 100644 --- a/src/mod/languages/mod_lua/lua/lvm.h +++ b/src/mod/languages/mod_lua/lua/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lvm.h,v 2.18 2013/01/08 14:06:55 roberto Exp $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -13,24 +13,32 @@ #include "ltm.h" -#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) +#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) -#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ - (((o) = luaV_tonumber(o,n)) != NULL)) +#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) -#define equalobj(L,o1,o2) \ - (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) +#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) + +#define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2) + + +/* not to called directly */ +LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); -LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val); LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val); -LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); -LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); +LUAI_FUNC void luaV_finishOp (lua_State *L); +LUAI_FUNC void luaV_execute (lua_State *L); +LUAI_FUNC void luaV_concat (lua_State *L, int total); +LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op); +LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); #endif diff --git a/src/mod/languages/mod_lua/lua/lzio.c b/src/mod/languages/mod_lua/lua/lzio.c index 293edd59b0..8b77054e0b 100644 --- a/src/mod/languages/mod_lua/lua/lzio.c +++ b/src/mod/languages/mod_lua/lua/lzio.c @@ -1,6 +1,6 @@ /* -** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ -** a generic input stream interface +** $Id: lzio.c,v 1.35 2012/05/14 13:34:18 roberto Exp $ +** Buffered streams ** See Copyright Notice in lua.h */ @@ -25,23 +25,11 @@ int luaZ_fill (ZIO *z) { lua_unlock(L); buff = z->reader(L, z->data, &size); lua_lock(L); - if (buff == NULL || size == 0) return EOZ; - z->n = size - 1; + if (buff == NULL || size == 0) + return EOZ; + z->n = size - 1; /* discount char being returned */ z->p = buff; - return char2int(*(z->p++)); -} - - -int luaZ_lookahead (ZIO *z) { - if (z->n == 0) { - if (luaZ_fill(z) == EOZ) - return EOZ; - else { - z->n++; /* luaZ_fill removed first byte; put back it */ - z->p--; - } - } - return char2int(*z->p); + return cast_uchar(*(z->p++)); } @@ -58,8 +46,14 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { size_t luaZ_read (ZIO *z, void *b, size_t n) { while (n) { size_t m; - if (luaZ_lookahead(z) == EOZ) - return n; /* return number of missing bytes */ + if (z->n == 0) { /* no bytes in buffer? */ + if (luaZ_fill(z) == EOZ) /* try to read more */ + return n; /* no more input; return number of missing bytes */ + else { + z->n++; /* luaZ_fill consumed first byte; put it back */ + z->p--; + } + } m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ memcpy(b, z->p, m); z->n -= m; diff --git a/src/mod/languages/mod_lua/lua/lzio.h b/src/mod/languages/mod_lua/lua/lzio.h index 51d695d8c1..08682301e8 100644 --- a/src/mod/languages/mod_lua/lua/lzio.h +++ b/src/mod/languages/mod_lua/lua/lzio.h @@ -1,5 +1,5 @@ /* -** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ +** $Id: lzio.h,v 1.26 2011/07/15 12:48:03 roberto Exp $ ** Buffered streams ** See Copyright Notice in lua.h */ @@ -17,9 +17,8 @@ typedef struct Zio ZIO; -#define char2int(c) cast(int, cast(unsigned char, (c))) +#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) -#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) typedef struct Mbuffer { char *buffer; @@ -47,7 +46,6 @@ LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data); LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ -LUAI_FUNC int luaZ_lookahead (ZIO *z); @@ -56,7 +54,7 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z); struct Zio { size_t n; /* bytes still unread */ const char *p; /* current position in buffer */ - lua_Reader reader; + lua_Reader reader; /* reader function */ void* data; /* additional data */ lua_State *L; /* Lua state (for reader) */ }; diff --git a/src/mod/languages/mod_lua/lua/print.c b/src/mod/languages/mod_lua/lua/print.c deleted file mode 100644 index e240cfc3c6..0000000000 --- a/src/mod/languages/mod_lua/lua/print.c +++ /dev/null @@ -1,227 +0,0 @@ -/* -** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ -** print bytecodes -** See Copyright Notice in lua.h -*/ - -#include -#include - -#define luac_c -#define LUA_CORE - -#include "ldebug.h" -#include "lobject.h" -#include "lopcodes.h" -#include "lundump.h" - -#define PrintFunction luaU_print - -#define Sizeof(x) ((int)sizeof(x)) -#define VOID(p) ((const void*)(p)) - -static void PrintString(const TString* ts) -{ - const char* s=getstr(ts); - size_t i,n=ts->tsv.len; - putchar('"'); - for (i=0; ik[i]; - switch (ttype(o)) - { - case LUA_TNIL: - printf("nil"); - break; - case LUA_TBOOLEAN: - printf(bvalue(o) ? "true" : "false"); - break; - case LUA_TNUMBER: - printf(LUA_NUMBER_FMT,nvalue(o)); - break; - case LUA_TSTRING: - PrintString(rawtsvalue(o)); - break; - default: /* cannot happen */ - printf("? type=%d",ttype(o)); - break; - } -} - -static void PrintCode(const Proto* f) -{ - const Instruction* code=f->code; - int pc,n=f->sizecode; - for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); - printf("%-9s\t",luaP_opnames[o]); - switch (getOpMode(o)) - { - case iABC: - printf("%d",a); - if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); - if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); - break; - case iABx: - if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); - break; - case iAsBx: - if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); - break; - } - switch (o) - { - case OP_LOADK: - printf("\t; "); PrintConstant(f,bx); - break; - case OP_GETUPVAL: - case OP_SETUPVAL: - printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); - break; - case OP_GETGLOBAL: - case OP_SETGLOBAL: - printf("\t; %s",svalue(&f->k[bx])); - break; - case OP_GETTABLE: - case OP_SELF: - if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } - break; - case OP_SETTABLE: - case OP_ADD: - case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_POW: - case OP_EQ: - case OP_LT: - case OP_LE: - if (ISK(b) || ISK(c)) - { - printf("\t; "); - if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); - printf(" "); - if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); - } - break; - case OP_JMP: - case OP_FORLOOP: - case OP_FORPREP: - printf("\t; to %d",sbx+pc+2); - break; - case OP_CLOSURE: - printf("\t; %p",VOID(f->p[bx])); - break; - case OP_SETLIST: - if (c==0) printf("\t; %d",(int)code[++pc]); - else printf("\t; %d",c); - break; - default: - break; - } - printf("\n"); - } -} - -#define SS(x) (x==1)?"":"s" -#define S(x) x,SS(x) - -static void PrintHeader(const Proto* f) -{ - const char* s=getstr(f->source); - if (*s=='@' || *s=='=') - s++; - else if (*s==LUA_SIGNATURE[0]) - s="(bstring)"; - else - s="(string)"; - printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", - (f->linedefined==0)?"main":"function",s, - f->linedefined,f->lastlinedefined, - S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); - printf("%d%s param%s, %d slot%s, %d upvalue%s, ", - f->numparams,f->is_vararg?"+":"",SS(f->numparams), - S(f->maxstacksize),S(f->nups)); - printf("%d local%s, %d constant%s, %d function%s\n", - S(f->sizelocvars),S(f->sizek),S(f->sizep)); -} - -static void PrintConstants(const Proto* f) -{ - int i,n=f->sizek; - printf("constants (%d) for %p:\n",n,VOID(f)); - for (i=0; isizelocvars; - printf("locals (%d) for %p:\n",n,VOID(f)); - for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); - } -} - -static void PrintUpvalues(const Proto* f) -{ - int i,n=f->sizeupvalues; - printf("upvalues (%d) for %p:\n",n,VOID(f)); - if (f->upvalues==NULL) return; - for (i=0; iupvalues[i])); - } -} - -void PrintFunction(const Proto* f, int full) -{ - int i,n=f->sizep; - PrintHeader(f); - PrintCode(f); - if (full) - { - PrintConstants(f); - PrintLocals(f); - PrintUpvalues(f); - } - for (i=0; ip[i],full); -} diff --git a/src/mod/languages/mod_lua/mod_lua.cpp b/src/mod/languages/mod_lua/mod_lua.cpp index 9715f0dc74..642a9c9b66 100644 --- a/src/mod/languages/mod_lua/mod_lua.cpp +++ b/src/mod/languages/mod_lua/mod_lua.cpp @@ -65,7 +65,7 @@ static void lua_uninit(lua_State * L) static int traceback(lua_State * L) { - lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + lua_getglobal(L, "debug"); if (!lua_istable(L, -1)) { lua_pop(L, 1); return 1; @@ -113,7 +113,7 @@ int docall(lua_State * L, int narg, int nresults, int perror) static lua_State *lua_init(void) { - lua_State *L = lua_open(); + lua_State *L = luaL_newstate(); int error = 0; if (L) { @@ -266,7 +266,7 @@ static switch_xml_t lua_fetch(const char *section, return NULL; } - lua_getfield(L, LUA_GLOBALSINDEX, "XML_STRING"); + lua_getglobal(L, "XML_STRING"); str = lua_tostring(L, 1); if (str) { @@ -581,7 +581,7 @@ SWITCH_STANDARD_DIALPLAN(lua_dialplan_hunt) lua_parse_and_execute(L, cmd); /* expecting ACTIONS = { {"app1", "app_data1"}, { "app2" }, "app3" } -- each of three is valid */ - lua_getfield(L, LUA_GLOBALSINDEX, "ACTIONS"); + lua_getglobal(L, "ACTIONS"); if (!lua_istable(L, 1)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Global variable ACTIONS may only be a table\n"); diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index 591cef641a..b1ff6d3a55 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -7913,7 +7913,7 @@ static swig_lua_class _wrap_class_LUA_Dbh = { "Dbh", &SWIGTYPE_p_LUA__Dbh,_wrap_ } #endif -static const struct luaL_reg swig_commands[] = { +static const struct luaL_Reg swig_commands[] = { { "setGlobalVariable", _wrap_setGlobalVariable}, { "getGlobalVariable", _wrap_getGlobalVariable}, { "consoleLog", _wrap_consoleLog}, @@ -8325,7 +8325,7 @@ SWIGEXPORT int SWIG_init(lua_State* L) { int i; /* start with global table */ - lua_pushvalue(L,LUA_GLOBALSINDEX); + lua_pushglobaltable(L); /* SWIG's internal initalisation */ SWIG_InitializeModule((void*)L); SWIG_PropagateClientData(); From 81a48a9e4e1074551e001ce089fd4bfde168997f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 13 Nov 2013 21:06:04 +0500 Subject: [PATCH 071/656] missed a few files in new lua commit --- src/mod/languages/mod_lua/lua/lbitlib.c | 211 +++++++++++++++++++++++ src/mod/languages/mod_lua/lua/lcorolib.c | 155 +++++++++++++++++ src/mod/languages/mod_lua/lua/lctype.c | 52 ++++++ src/mod/languages/mod_lua/lua/lctype.h | 95 ++++++++++ src/mod/languages/mod_lua/lua/lua.hpp | 9 + 5 files changed, 522 insertions(+) create mode 100644 src/mod/languages/mod_lua/lua/lbitlib.c create mode 100644 src/mod/languages/mod_lua/lua/lcorolib.c create mode 100644 src/mod/languages/mod_lua/lua/lctype.c create mode 100644 src/mod/languages/mod_lua/lua/lctype.h create mode 100644 src/mod/languages/mod_lua/lua/lua.hpp diff --git a/src/mod/languages/mod_lua/lua/lbitlib.c b/src/mod/languages/mod_lua/lua/lbitlib.c new file mode 100644 index 0000000000..9637532e3d --- /dev/null +++ b/src/mod/languages/mod_lua/lua/lbitlib.c @@ -0,0 +1,211 @@ +/* +** $Id: lbitlib.c,v 1.18 2013/03/19 13:19:12 roberto Exp $ +** Standard library for bitwise operations +** See Copyright Notice in lua.h +*/ + +#define lbitlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* number of bits to consider in a number */ +#if !defined(LUA_NBITS) +#define LUA_NBITS 32 +#endif + + +#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) + +/* macro to trim extra bits */ +#define trim(x) ((x) & ALLONES) + + +/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ +#define mask(n) (~((ALLONES << 1) << ((n) - 1))) + + +typedef lua_Unsigned b_uint; + + + +static b_uint andaux (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = ~(b_uint)0; + for (i = 1; i <= n; i++) + r &= luaL_checkunsigned(L, i); + return trim(r); +} + + +static int b_and (lua_State *L) { + b_uint r = andaux(L); + lua_pushunsigned(L, r); + return 1; +} + + +static int b_test (lua_State *L) { + b_uint r = andaux(L); + lua_pushboolean(L, r != 0); + return 1; +} + + +static int b_or (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r |= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_xor (lua_State *L) { + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r ^= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_not (lua_State *L) { + b_uint r = ~luaL_checkunsigned(L, 1); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_shift (lua_State *L, b_uint r, int i) { + if (i < 0) { /* shift right? */ + i = -i; + r = trim(r); + if (i >= LUA_NBITS) r = 0; + else r >>= i; + } + else { /* shift left */ + if (i >= LUA_NBITS) r = 0; + else r <<= i; + r = trim(r); + } + lua_pushunsigned(L, r); + return 1; +} + + +static int b_lshift (lua_State *L) { + return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); +} + + +static int b_rshift (lua_State *L) { + return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); +} + + +static int b_arshift (lua_State *L) { + b_uint r = luaL_checkunsigned(L, 1); + int i = luaL_checkint(L, 2); + if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) + return b_shift(L, r, -i); + else { /* arithmetic shift for 'negative' number */ + if (i >= LUA_NBITS) r = ALLONES; + else + r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ + lua_pushunsigned(L, r); + return 1; + } +} + + +static int b_rot (lua_State *L, int i) { + b_uint r = luaL_checkunsigned(L, 1); + i &= (LUA_NBITS - 1); /* i = i % NBITS */ + r = trim(r); + r = (r << i) | (r >> (LUA_NBITS - i)); + lua_pushunsigned(L, trim(r)); + return 1; +} + + +static int b_lrot (lua_State *L) { + return b_rot(L, luaL_checkint(L, 2)); +} + + +static int b_rrot (lua_State *L) { + return b_rot(L, -luaL_checkint(L, 2)); +} + + +/* +** get field and width arguments for field-manipulation functions, +** checking whether they are valid. +** ('luaL_error' called without 'return' to avoid later warnings about +** 'width' being used uninitialized.) +*/ +static int fieldargs (lua_State *L, int farg, int *width) { + int f = luaL_checkint(L, farg); + int w = luaL_optint(L, farg + 1, 1); + luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); + luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); + if (f + w > LUA_NBITS) + luaL_error(L, "trying to access non-existent bits"); + *width = w; + return f; +} + + +static int b_extract (lua_State *L) { + int w; + b_uint r = luaL_checkunsigned(L, 1); + int f = fieldargs(L, 2, &w); + r = (r >> f) & mask(w); + lua_pushunsigned(L, r); + return 1; +} + + +static int b_replace (lua_State *L) { + int w; + b_uint r = luaL_checkunsigned(L, 1); + b_uint v = luaL_checkunsigned(L, 2); + int f = fieldargs(L, 3, &w); + int m = mask(w); + v &= m; /* erase bits outside given width */ + r = (r & ~(m << f)) | (v << f); + lua_pushunsigned(L, r); + return 1; +} + + +static const luaL_Reg bitlib[] = { + {"arshift", b_arshift}, + {"band", b_and}, + {"bnot", b_not}, + {"bor", b_or}, + {"bxor", b_xor}, + {"btest", b_test}, + {"extract", b_extract}, + {"lrotate", b_lrot}, + {"lshift", b_lshift}, + {"replace", b_replace}, + {"rrotate", b_rrot}, + {"rshift", b_rshift}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_bit32 (lua_State *L) { + luaL_newlib(L, bitlib); + return 1; +} + diff --git a/src/mod/languages/mod_lua/lua/lcorolib.c b/src/mod/languages/mod_lua/lua/lcorolib.c new file mode 100644 index 0000000000..1326c8146c --- /dev/null +++ b/src/mod/languages/mod_lua/lua/lcorolib.c @@ -0,0 +1,155 @@ +/* +** $Id: lcorolib.c,v 1.5 2013/02/21 13:44:53 roberto Exp $ +** Coroutine Library +** See Copyright Notice in lua.h +*/ + + +#include + + +#define lcorolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status; + if (!lua_checkstack(co, narg)) { + lua_pushliteral(L, "too many arguments to resume"); + return -1; /* error flag */ + } + if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { + lua_pushliteral(L, "cannot resume dead coroutine"); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + status = lua_resume(co, L, narg); + if (status == LUA_OK || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); + return -1; /* error flag */ + } + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + return lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL; + luaL_checktype(L, 1, LUA_TFUNCTION); + NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + if (L == co) lua_pushliteral(L, "running"); + else { + switch (lua_status(co)) { + case LUA_YIELD: + lua_pushliteral(L, "suspended"); + break; + case LUA_OK: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + lua_pushliteral(L, "normal"); /* it is running */ + else if (lua_gettop(co) == 0) + lua_pushliteral(L, "dead"); + else + lua_pushliteral(L, "suspended"); /* initial state */ + break; + } + default: /* some error occurred */ + lua_pushliteral(L, "dead"); + break; + } + } + return 1; +} + + +static int luaB_corunning (lua_State *L) { + int ismain = lua_pushthread(L); + lua_pushboolean(L, ismain); + return 2; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + + + +LUAMOD_API int luaopen_coroutine (lua_State *L) { + luaL_newlib(L, co_funcs); + return 1; +} + diff --git a/src/mod/languages/mod_lua/lua/lctype.c b/src/mod/languages/mod_lua/lua/lctype.c new file mode 100644 index 0000000000..55e433a5dd --- /dev/null +++ b/src/mod/languages/mod_lua/lua/lctype.c @@ -0,0 +1,52 @@ +/* +** $Id: lctype.c,v 1.11 2011/10/03 16:19:23 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#define lctype_c +#define LUA_CORE + +#include "lctype.h" + +#if !LUA_USE_CTYPE /* { */ + +#include + +LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { + 0x00, /* EOZ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ + 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, + 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ + 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#endif /* } */ diff --git a/src/mod/languages/mod_lua/lua/lctype.h b/src/mod/languages/mod_lua/lua/lctype.h new file mode 100644 index 0000000000..99c7d12237 --- /dev/null +++ b/src/mod/languages/mod_lua/lua/lctype.h @@ -0,0 +1,95 @@ +/* +** $Id: lctype.h,v 1.12 2011/07/15 12:50:29 roberto Exp $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lctype_h +#define lctype_h + +#include "lua.h" + + +/* +** WARNING: the functions defined here do not necessarily correspond +** to the similar functions in the standard C ctype.h. They are +** optimized for the specific needs of Lua +*/ + +#if !defined(LUA_USE_CTYPE) + +#if 'A' == 65 && '0' == 48 +/* ASCII case: can use its own tables; faster and fixed */ +#define LUA_USE_CTYPE 0 +#else +/* must use standard C ctype */ +#define LUA_USE_CTYPE 1 +#endif + +#endif + + +#if !LUA_USE_CTYPE /* { */ + +#include + +#include "llimits.h" + + +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 + + +#define MASK(B) (1 << (B)) + + +/* +** add 1 to char to allow index -1 (EOZ) +*/ +#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) + +/* +** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' +*/ +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) + +/* +** this 'ltolower' only works for alphabetic characters +*/ +#define ltolower(c) ((c) | ('A' ^ 'a')) + + +/* two more entries for 0 and -1 (EOZ) */ +LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; + + +#else /* }{ */ + +/* +** use standard C ctypes +*/ + +#include + + +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) + +#define ltolower(c) (tolower(c)) + +#endif /* } */ + +#endif + diff --git a/src/mod/languages/mod_lua/lua/lua.hpp b/src/mod/languages/mod_lua/lua/lua.hpp new file mode 100644 index 0000000000..ec417f5946 --- /dev/null +++ b/src/mod/languages/mod_lua/lua/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} From e603c17de817965ac8c278166794fc1e5982b639 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 13 Nov 2013 21:41:37 +0500 Subject: [PATCH 072/656] try to improve performance of subscribe sip handler --- src/mod/endpoints/mod_sofia/sofia_glue.c | 1 + src/mod/endpoints/mod_sofia/sofia_presence.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index d5bbe14c55..8c9f028348 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2106,6 +2106,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile) "create index sr_orig_server_host on sip_registrations (orig_server_host)", "create index sr_orig_hostname on sip_registrations (orig_hostname)", "create index ss_call_id on sip_subscriptions (call_id)", + "create index ss_multi on sip_subscriptions (call_id, profile_name, hostname)", "create index ss_hostname on sip_subscriptions (hostname)", "create index ss_network_ip on sip_subscriptions (network_ip)", "create index ss_sip_user on sip_subscriptions (sip_user)", diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index ef998c9c88..ef28993d89 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3587,8 +3587,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, int found_proto = 0; const char *use_to_tag; char to_tag[13] = ""; - char buf[32] = ""; - int subbed = 0; + char buf[80] = ""; if (!sip) { return; @@ -3751,8 +3750,8 @@ void sofia_presence_handle_sip_i_subscribe(int status, } if ((sub_state != nua_substate_terminated)) { - sql = switch_mprintf("select count(*) from sip_subscriptions where call_id='%q' and hostname='%q' and profile_name='%q'", - call_id, mod_sofia_globals.hostname, profile->name); + sql = switch_mprintf("select call_id from sip_subscriptions where call_id='%q' and profile_name='%q' and hostname='%q'", + call_id, profile->name, mod_sofia_globals.hostname); sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf)); @@ -3763,7 +3762,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_safe_free(sql); - if ((subbed = atoi(buf)) > 0) { + if (!zstr(buf)) { sub_state = nua_substate_active; } } @@ -3774,9 +3773,9 @@ void sofia_presence_handle_sip_i_subscribe(int status, sql = switch_mprintf("update sip_subscriptions " "set expires=%ld " - "where hostname='%q' and profile_name='%q' and call_id='%q' and profile_name='%q'", - (long) switch_epoch_time_now(NULL) + exp_delta, mod_sofia_globals.hostname, profile->name, - call_id, profile->name); + "where call_id='%q' and profile_name='%q' and hostname='%q'", + (long) switch_epoch_time_now(NULL) + exp_delta, + call_id, profile->name, mod_sofia_globals.hostname); if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, From b90f2446d495657f912f130460ff80b09a9108d7 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 13 Nov 2013 11:42:30 -0500 Subject: [PATCH 073/656] mod_mongo: add support for query options --- src/mod/applications/mod_mongo/mod_mongo.cpp | 39 ++++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_mongo/mod_mongo.cpp b/src/mod/applications/mod_mongo/mod_mongo.cpp index 8c3536def2..8bfe724a63 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.cpp +++ b/src/mod/applications/mod_mongo/mod_mongo.cpp @@ -43,6 +43,33 @@ static struct { char *finalize; } globals; +static int parse_query_options(char *query_options_str) +{ + int query_options = 0; + if (strstr(query_options_str, "cursorTailable")) { + query_options |= QueryOption_CursorTailable; + } + if (strstr(query_options_str, "slaveOk")) { + query_options |= QueryOption_SlaveOk; + } + if (strstr(query_options_str, "oplogReplay")) { + query_options |= QueryOption_OplogReplay; + } + if (strstr(query_options_str, "noCursorTimeout")) { + query_options |= QueryOption_NoCursorTimeout; + } + if (strstr(query_options_str, "awaitData")) { + query_options |= QueryOption_AwaitData; + } + if (strstr(query_options_str, "exhaust")) { + query_options |= QueryOption_Exhaust; + } + if (strstr(query_options_str, "partialResults")) { + query_options |= QueryOption_PartialResults; + } + return query_options; +} + SWITCH_STANDARD_API(mongo_mapreduce_function) { switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -101,11 +128,11 @@ SWITCH_STANDARD_API(mongo_mapreduce_function) return status; } - SWITCH_STANDARD_API(mongo_find_one_function) { switch_status_t status = SWITCH_STATUS_SUCCESS; - char *ns = NULL, *json_query = NULL, *json_fields = NULL; + char *ns = NULL, *json_query = NULL, *json_fields = NULL, *query_options_str = NULL; + int query_options = 0; ns = strdup(cmd); switch_assert(ns != NULL); @@ -114,6 +141,12 @@ SWITCH_STANDARD_API(mongo_find_one_function) *json_query++ = '\0'; if ((json_fields = strchr(json_query, DELIMITER))) { *json_fields++ = '\0'; + if ((query_options_str = strchr(json_fields, DELIMITER))) { + *query_options_str++ = '\0'; + if (!zstr(query_options_str)) { + query_options = parse_query_options(query_options_str); + } + } } } @@ -127,7 +160,7 @@ SWITCH_STANDARD_API(mongo_find_one_function) conn = mongo_connection_pool_get(globals.conn_pool); if (conn) { - BSONObj res = conn->findOne(ns, Query(query), &fields); + BSONObj res = conn->findOne(ns, Query(query), &fields, query_options); mongo_connection_pool_put(globals.conn_pool, conn, SWITCH_FALSE); stream->write_function(stream, "-OK\n%s\n", res.jsonString().c_str()); From 43da8509f5648b924a889aeb6af2fa354ba89cc0 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 13 Nov 2013 11:45:39 -0500 Subject: [PATCH 074/656] mod_mongo: update mongo_find_one syntax --- src/mod/applications/mod_mongo/mod_mongo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_mongo/mod_mongo.cpp b/src/mod/applications/mod_mongo/mod_mongo.cpp index 8bfe724a63..8057277f15 100644 --- a/src/mod/applications/mod_mongo/mod_mongo.cpp +++ b/src/mod/applications/mod_mongo/mod_mongo.cpp @@ -24,6 +24,7 @@ * Contributor(s): * * Tamas Cseke + * Christopher Rienzo * * mod_mongo.cpp -- API for MongoDB * @@ -33,7 +34,7 @@ #include "mod_mongo.h" #define DELIMITER ';' -#define FIND_ONE_SYNTAX "mongo_find_one ns; query; fields" +#define FIND_ONE_SYNTAX "mongo_find_one ns; query; fields; options" #define MAPREDUCE_SYNTAX "mongo_mapreduce ns; query" static struct { From 37d566c6f6838a82efe55fa06811170e9cccb805 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 13 Nov 2013 11:14:34 -0600 Subject: [PATCH 075/656] FS-5943 --resolve --- src/mod/applications/mod_voicemail/mod_voicemail.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 07d4d2fe95..6f2e5d68c9 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -28,6 +28,7 @@ * John Wehle (john@feith.com) * Raymond Chandler * Kristin King + * Emmanuel Schmidbauer * * mod_voicemail.c -- Voicemail Module * @@ -3345,7 +3346,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p int send_mail = 0; cc_t cc = { 0 }; char *read_flags = NORMAL_FLAG_STRING; - char *operator_ext = NULL; + const char *operator_ext = switch_channel_get_variable(channel, "vm_operator_extension"); char buf[2]; char key_buf[80]; char *greet_path = NULL; @@ -3422,7 +3423,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p vm_enabled = !switch_false(val); } else if (!strcasecmp(var, "vm-message-ext")) { vm_ext = switch_core_session_strdup(session, val); - } else if (!strcasecmp(var, "vm-operator-extension")) { + } else if (!strcasecmp(var, "vm-operator-extension") && (zstr(operator_ext))) { operator_ext = switch_core_session_strdup(session, val); } } From f9a19ee57f713dd54e93e9d89415ccdecf2b6442 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 13 Nov 2013 11:13:36 -0600 Subject: [PATCH 076/656] FS-5880 --resolve --- .../mod_nibblebill/mod_nibblebill.c | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index fff12336f1..5174c7fa67 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -28,9 +28,10 @@ * Contributor(s): * Darren Schreiber * Rupa Schomaker + * Emmanuel Schmidbauer * * mod_nibblebill.c - Nibble Billing - * Purpose is to allow real-time debiting of credit or cash from a database while calls are in progress. I had the following goals: + * Purpose is to allow real-time debiting of credit or cash from a database while calls are in progress. I had the following goals: * * Debit credit/cash from accounts real-time * Allow for billing at different rates during a single call @@ -91,6 +92,10 @@ static struct { /* Other options */ int global_heartbeat; /* Supervise and bill every X seconds, 0 means off */ + /* Channel variable name options */ + char *var_name_rate; + char *var_name_account; + /* Database settings */ char *dbname; char *odbc_dsn; @@ -125,6 +130,8 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_custom_sql_lookup, globals.custom_s SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_percall_action, globals.percall_action); SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_lowbal_action, globals.lowbal_action); SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_nobal_action, globals.nobal_action); +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_var_name_rate, globals.var_name_rate); +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_var_name_account, globals.var_name_account); static switch_cache_db_handle_t *nibblebill_get_db_handle(void) { @@ -242,6 +249,10 @@ static switch_status_t nibblebill_load_config(void) set_global_nobal_action(val); } else if (!strcasecmp(var, "nobal_amt")) { globals.nobal_amt = atof(val); + } else if (!strcasecmp(var, "var_name_rate")) { + set_global_var_name_rate(val); + } else if (!strcasecmp(var, "var_name_account")) { + set_global_var_name_account(val); } else if (!strcasecmp(var, "global_heartbeat")) { globals.global_heartbeat = atoi(val); } @@ -260,6 +271,12 @@ static switch_status_t nibblebill_load_config(void) if (zstr(globals.nobal_action)) { set_global_nobal_action("hangup"); } + if (zstr(globals.var_name_rate)) { + set_global_var_name_rate("nibble_rate"); + } + if (zstr(globals.var_name_account)) { + set_global_var_name_account("nibble_account"); + } if (globals.odbc_dsn) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG @@ -449,10 +466,10 @@ static switch_status_t do_billing(switch_core_session_t *session) } /* Variables kept in FS but relevant only to this module */ - billrate = switch_channel_get_variable(channel, "nibble_rate"); + billrate = switch_channel_get_variable(channel, globals.var_name_rate); billincrement = switch_channel_get_variable(channel, "nibble_increment"); - billaccount = switch_channel_get_variable(channel, "nibble_account"); - + billaccount = switch_channel_get_variable(channel, globals.var_name_account); + if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) { nobal_amt = atof(switch_channel_get_variable(channel, "nobal_amt")); } @@ -707,7 +724,7 @@ static void nibblebill_resume(switch_core_session_t *session) switch_mutex_lock(globals.mutex); } - billrate = switch_channel_get_variable(channel, "nibble_rate"); + billrate = switch_channel_get_variable(channel, globals.var_name_rate); /* Calculate how much was "lost" to billings during pause - we do this here because you never know when the billrate may change during a call */ nibble_data->bill_adjustments += (atof(billrate) / 1000000 / 60) * ((ts - nibble_data->pausets)); @@ -800,7 +817,7 @@ static void nibblebill_adjust(switch_core_session_t *session, double amount) /* Variables kept in FS but relevant only to this module */ - billaccount = switch_channel_get_variable(channel, "nibble_account"); + billaccount = switch_channel_get_variable(channel, globals.var_name_account); /* Return if there's no billing information on this session */ if (!billaccount) { @@ -900,9 +917,9 @@ static switch_status_t sched_billing(switch_core_session_t *session) } /* Variables kept in FS but relevant only to this module */ - billrate = switch_channel_get_variable(channel, "nibble_rate"); - billaccount = switch_channel_get_variable(channel, "nibble_account"); - + billrate = switch_channel_get_variable(channel, globals.var_name_rate); + billaccount = switch_channel_get_variable(channel, globals.var_name_account); + /* Return if there's no billing information on this session */ if (!billrate || !billaccount) { return SWITCH_STATUS_SUCCESS; @@ -930,7 +947,7 @@ static switch_status_t process_hangup(switch_core_session_t *session) /* Now go handle like normal billing */ do_billing(session); - billaccount = switch_channel_get_variable(channel, "nibble_account"); + billaccount = switch_channel_get_variable(channel, globals.var_name_account); if (billaccount) { switch_channel_set_variable_printf(channel, "nibble_current_balance", "%f", get_balance(billaccount, channel)); } @@ -1012,6 +1029,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_nibblebill_shutdown) switch_safe_free(globals.percall_action); switch_safe_free(globals.lowbal_action); switch_safe_free(globals.nobal_action); + switch_safe_free(globals.var_name_rate); + switch_safe_free(globals.var_name_account); return SWITCH_STATUS_UNLOAD; } From c469e7ada294a084be0d318255684a5306afab85 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 14 Nov 2013 00:43:15 +0500 Subject: [PATCH 077/656] cleanup ESL a little --- libs/esl/Makefile | 7 ++- libs/esl/ivrd.c | 2 +- libs/esl/src/esl.c | 109 ++++++++++++++++++++++++------------- libs/esl/src/esl_buffer.c | 4 +- libs/esl/src/include/esl.h | 2 +- libs/esl/testserver.c | 2 +- 6 files changed, 81 insertions(+), 45 deletions(-) diff --git a/libs/esl/Makefile b/libs/esl/Makefile index 727bf3169f..3e59a9dc0c 100644 --- a/libs/esl/Makefile +++ b/libs/esl/Makefile @@ -17,7 +17,7 @@ SOLINK=-shared -Xlinker -x # comment the next line to disable c++ (no swig mods for you then) OBJS += src/esl_oop.o -all: $(MYLIB) fs_cli testclient testserver ivrd +all: $(MYLIB) fs_cli testclient testserver testserver_fork ivrd $(MYLIB): $(OBJS) $(HEADERS) $(SRC) ar rcs $(MYLIB) $(OBJS) @@ -26,6 +26,9 @@ $(MYLIB): $(OBJS) $(HEADERS) $(SRC) testserver: $(MYLIB) testserver.c $(CC) $(CC_CFLAGS) $(CFLAGS) testserver.c -o testserver $(LDFLAGS) $(LIBS) +testserver_fork: $(MYLIB) testserver_fork.c + $(CC) $(CC_CFLAGS) $(CFLAGS) testserver_fork.c -o testserver_fork $(LDFLAGS) $(LIBS) + ivrd: $(MYLIB) ivrd.c $(CC) $(CC_CFLAGS) $(CFLAGS) ivrd.c -o ivrd $(LDFLAGS) $(LIBS) @@ -42,7 +45,7 @@ fs_cli: $(MYLIB) fs_cli.c $(CXX) $(CXX_CFLAGS) $(CXXFLAGS) -c $< -o $@ clean: - rm -f *.o src/*.o testclient testserver ivrd fs_cli libesl.a *~ src/*~ src/include/*~ + rm -f *.o src/*.o testclient testserver testserver_fork ivrd fs_cli libesl.a *~ src/*~ src/include/*~ $(MAKE) -C perl clean $(MAKE) -C php clean $(MAKE) -C lua clean diff --git a/libs/esl/ivrd.c b/libs/esl/ivrd.c index 0d1a98ec4f..9e4326d58a 100644 --- a/libs/esl/ivrd.c +++ b/libs/esl/ivrd.c @@ -166,7 +166,7 @@ int main(int argc, char *argv[]) } else { printf("Starting forking listener.\n"); fflush(stdout); - esl_listen(ip, port, my_forking_callback); + esl_listen(ip, port, my_forking_callback, NULL); } return 0; diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index ede0675df0..7ddda5fd30 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -476,15 +476,14 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s esl_send_recv(handle, "connect\n\n"); - if (handle->last_sr_event) { handle->info_event = handle->last_sr_event; handle->last_sr_event = NULL; return ESL_SUCCESS; } - handle->connected = 0; - + esl_disconnect(handle); + return ESL_FAIL; } @@ -658,16 +657,41 @@ static void *client_thread(esl_thread_t *me, void *obj) } -ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback) +static int prepare_sock(esl_socket_t sock) +{ + int r = 0; + +#ifdef WIN32 + u_long arg = 1; + if (ioctlsocket(sock, FIONBIO, &arg) == SOCKET_ERROR) { + r = -1; + } +#else + int fd_flags = fcntl(sock, F_GETFL, 0); + if (fcntl(sock, F_SETFL, fd_flags | O_NONBLOCK)) { + r = -1; + } +#endif + +} + + +ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, esl_socket_t *server_sockP) { esl_socket_t server_sock = ESL_SOCK_INVALID; struct sockaddr_in addr; esl_status_t status = ESL_SUCCESS; + if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { return ESL_FAIL; } + if (server_sockP) { + *server_sockP = server_sock; + } + + esl_socket_reuseaddr(server_sock); memset(&addr, 0, sizeof(addr)); @@ -700,7 +724,7 @@ ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_list status = ESL_FAIL; goto end; } - + prepare_sock(client_sock); callback(server_sock, client_sock, &echoClntAddr); } @@ -759,6 +783,8 @@ ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, goto end; } + prepare_sock(client_sock); + handler = malloc(sizeof(*handler)); esl_assert(handler); @@ -767,7 +793,6 @@ ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, handler->server_sock = server_sock; handler->client_sock = client_sock; handler->addr = echoClntAddr; - esl_thread_create_detached(client_thread, handler); } @@ -1078,7 +1103,7 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char * return ESL_SUCCESS; fail: - + handle->connected = 0; esl_disconnect(handle); @@ -1089,7 +1114,8 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle) { esl_mutex_t *mutex = handle->mutex; esl_status_t status = ESL_FAIL; - + esl_event_t *ep; + if (handle->destroyed) { return ESL_FAIL; } @@ -1098,10 +1124,17 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle) esl_mutex_lock(mutex); } - handle->destroyed = 1; + handle->connected = 0; - esl_event_safe_destroy(&handle->race_event); + ep = handle->race_event; + + while(ep) { + esl_event_t *e = ep; + ep = ep->next; + esl_event_safe_destroy(&e); + } + esl_event_safe_destroy(&handle->last_event); esl_event_safe_destroy(&handle->last_sr_event); esl_event_safe_destroy(&handle->last_ievent); @@ -1119,11 +1152,13 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle) esl_mutex_unlock(mutex); esl_mutex_destroy(&mutex); } - + if (handle->packet_buf) { esl_buffer_destroy(&handle->packet_buf); } - + + memset(handle, 0, sizeof(*handle)); + handle->destroyed = 1; return status; } @@ -1150,7 +1185,11 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms esl_mutex_unlock(handle->mutex); } - activity = esl_wait_sock(handle->sock, ms, ESL_POLL_READ|ESL_POLL_ERROR); + if (handle->packet_buf && esl_buffer_inuse(handle->packet_buf)) { + activity = ESL_POLL_READ; + } else { + activity = esl_wait_sock(handle->sock, ms, ESL_POLL_READ|ESL_POLL_ERROR); + } if (activity < 0) { handle->connected = 0; @@ -1161,9 +1200,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms return ESL_BREAK; } - activity = esl_wait_sock(handle->sock, ms, ESL_POLL_READ|ESL_POLL_ERROR); - - if (activity < 0) { handle->connected = 0; status = ESL_FAIL; @@ -1183,21 +1219,23 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t datalen) { - int activity; + esl_ssize_t activity = -1; - while (handle->connected) { - activity = esl_wait_sock(handle->sock, 1000, ESL_POLL_READ|ESL_POLL_ERROR); - - if (activity > 0 && (activity & ESL_POLL_READ)) { - return recv(handle->sock, data, datalen, 0); + if (handle->connected) { + if ((activity = esl_wait_sock(handle->sock, -1, ESL_POLL_READ|ESL_POLL_ERROR)) > 0) { + if ((activity & ESL_POLL_ERROR)) { + activity = -1; + } else if ((activity & ESL_POLL_READ)) { + activity = recv(handle->sock, data, datalen, 0); + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { + activity = 0; + } + } } - if (activity < 0) { - return errno == EINTR ? 0 : -1; - } } - return -1; + return activity; } ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event) @@ -1232,7 +1270,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ goto parse_event; } - while(!revent && handle->connected) { esl_size_t len1; @@ -1277,14 +1314,10 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ break; } - - rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1); - *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, rrval)) = '\0'; + rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1); + if (rrval == 0) { - if (++zc >= 100) { - goto fail; - } continue; } else if (rrval < 0) { if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err)))) @@ -1292,6 +1325,7 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ goto fail; } + *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, rrval)) = '\0'; zc = 0; esl_buffer_write(handle->packet_buf, handle->socket_buf, rrval); @@ -1317,19 +1351,16 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ sofar = esl_buffer_read(handle->packet_buf, body, len); } else { r = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1); - *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, r)) = '\0'; - + if (r < 0) { if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err)))) *(handle->err)=0; goto fail; } else if (r == 0) { - if (++zc >= 100) { - goto fail; - } continue; } + *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, r)) = '\0'; zc = 0; esl_buffer_write(handle->packet_buf, handle->socket_buf, r); @@ -1527,7 +1558,7 @@ ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char * esl_event_t *ep; for(ep = handle->race_event; ep && ep->next; ep = ep->next); - + if (ep) { ep->next = handle->last_sr_event; } else { diff --git a/libs/esl/src/esl_buffer.c b/libs/esl/src/esl_buffer.c index 40c7252c15..6095a56a21 100644 --- a/libs/esl/src/esl_buffer.c +++ b/libs/esl/src/esl_buffer.c @@ -54,6 +54,7 @@ ESL_DECLARE(esl_status_t) esl_buffer_create(esl_buffer_t **buffer, esl_size_t bl esl_buffer_t *new_buffer; new_buffer = malloc(sizeof(*new_buffer)); + if (new_buffer) { memset(new_buffer, 0, sizeof(*new_buffer)); @@ -335,9 +336,10 @@ ESL_DECLARE(void) esl_buffer_destroy(esl_buffer_t **buffer) { if (*buffer) { free((*buffer)->data); + (*buffer)->data = NULL; free(*buffer); } - + *buffer = NULL; } diff --git a/libs/esl/src/include/esl.h b/libs/esl/src/include/esl.h index 79c416a6d3..53b98ae72b 100644 --- a/libs/esl/src/include/esl.h +++ b/libs/esl/src/include/esl.h @@ -394,7 +394,7 @@ ESL_DECLARE(esl_status_t) esl_attach_handle(esl_handle_t *handle, esl_socket_t s \param callback Callback that will be called upon data received */ -ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback); +ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, esl_socket_t *server_sockP); ESL_DECLARE(esl_status_t) esl_listen_threaded(const char *host, esl_port_t port, esl_listen_callback_t callback, int max); /*! \brief Executes application with sendmsg to a specific UUID. Used for outbound socket. diff --git a/libs/esl/testserver.c b/libs/esl/testserver.c index f8eb78d1f3..13df29c332 100644 --- a/libs/esl/testserver.c +++ b/libs/esl/testserver.c @@ -48,7 +48,7 @@ static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struc int main(void) { esl_global_set_default_logger(7); - esl_listen_threaded("localhost", 8084, mycallback, 100000); + esl_listen_threaded("localhost", 8040, mycallback, 100000); return 0; } From c429de413911a4c9b3bedd7cd8f6476e5146d49c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 14 Nov 2013 01:38:00 +0500 Subject: [PATCH 078/656] fix build err --- libs/esl/src/esl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 7ddda5fd30..9b62e94aa4 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -672,6 +672,8 @@ static int prepare_sock(esl_socket_t sock) r = -1; } #endif + + return r; } @@ -1132,7 +1134,9 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle) while(ep) { esl_event_t *e = ep; ep = ep->next; - esl_event_safe_destroy(&e); + if (e) { + esl_event_destroy(&e); + } } esl_event_safe_destroy(&handle->last_event); @@ -1248,7 +1252,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ char *col; char *cl; esl_ssize_t len; - int zc = 0; if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) { return ESL_FAIL; @@ -1326,7 +1329,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ } *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, rrval)) = '\0'; - zc = 0; esl_buffer_write(handle->packet_buf, handle->socket_buf, rrval); } @@ -1361,8 +1363,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_ } *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, r)) = '\0'; - zc = 0; - esl_buffer_write(handle->packet_buf, handle->socket_buf, r); } From 300e55e56c2b0b139fd7e3f0b26744ee164473ef Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 14 Nov 2013 01:39:53 +0500 Subject: [PATCH 079/656] FS-5941 --resolve --- src/switch_core_io.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 1a5a0469fe..13c15874f4 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -185,7 +185,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi top: for(i = 0; i < 2; i++) { - if (session->dmachine[i] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { + if (session->dmachine[i]) { switch_channel_dtmf_lock(session->channel); switch_ivr_dmachine_ping(session->dmachine[i], NULL); switch_channel_dtmf_unlock(session->channel); @@ -1629,7 +1629,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_recv_dtmf(switch_core_sessio } if (!switch_test_flag(dtmf, DTMF_FLAG_SKIP_PROCESS)) { - if (session->dmachine[0] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { + if (session->dmachine[0]) { char str[2] = { dtmf->digit, '\0' }; switch_ivr_dmachine_feed(session->dmachine[0], str, NULL); fed = 1; @@ -1694,8 +1694,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_send_dtmf(switch_core_sessio return SWITCH_STATUS_SUCCESS; } } - - if (session->dmachine[1] && !switch_channel_test_flag(session->channel, CF_BROADCAST)) { + if (session->dmachine[1]) { char str[2] = { new_dtmf.digit, '\0' }; switch_ivr_dmachine_feed(session->dmachine[1], str, NULL); return SWITCH_STATUS_SUCCESS; From 9d2400b7ab2ac14e2857df28ebd8baebbedd24a7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 14 Nov 2013 01:48:48 +0500 Subject: [PATCH 080/656] doh --- libs/esl/testserver_fork.c | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 libs/esl/testserver_fork.c diff --git a/libs/esl/testserver_fork.c b/libs/esl/testserver_fork.c new file mode 100644 index 0000000000..54c0238a3c --- /dev/null +++ b/libs/esl/testserver_fork.c @@ -0,0 +1,72 @@ +#include +#include +#include + +static void mycallback(esl_socket_t server_sock, esl_socket_t client_sock, struct sockaddr_in *addr) +{ + esl_handle_t handle = {{0}}; + int done = 0; + esl_status_t status; + time_t exp = 0; + + if (fork()) { + return; + } + + if (esl_attach_handle(&handle, client_sock, addr) != ESL_SUCCESS) { + return; + } + + + esl_log(ESL_LOG_INFO, "Connected! %d\n", handle.sock); + + esl_filter(&handle, "unique-id", esl_event_get_header(handle.info_event, "caller-unique-id")); + esl_events(&handle, ESL_EVENT_TYPE_PLAIN, "SESSION_HEARTBEAT CHANNEL_ANSWER CHANNEL_ORIGINATE CHANNEL_PROGRESS CHANNEL_HANGUP " + "CHANNEL_BRIDGE CHANNEL_UNBRIDGE CHANNEL_OUTGOING CHANNEL_EXECUTE CHANNEL_EXECUTE_COMPLETE DTMF CUSTOM conference::maintenance"); + + esl_send_recv(&handle, "linger"); + + esl_execute(&handle, "answer", NULL, NULL); + esl_execute(&handle, "conference", "3000@default", NULL); + + while((status = esl_recv_timed(&handle, 1000)) != ESL_FAIL) { + if (done) { + if (time(NULL) >= exp) { + break; + } + } else if (status == ESL_SUCCESS) { + const char *type = esl_event_get_header(handle.last_event, "content-type"); + if (type && !strcasecmp(type, "text/disconnect-notice")) { + const char *dispo = esl_event_get_header(handle.last_event, "content-disposition"); + esl_log(ESL_LOG_INFO, "Got a disconnection notice dispostion: [%s]\n", dispo ? dispo : ""); + if (dispo && !strcmp(dispo, "linger")) { + done = 1; + esl_log(ESL_LOG_INFO, "Waiting 5 seconds for any remaining events.\n"); + exp = time(NULL) + 5; + } + } + } + } + + esl_log(ESL_LOG_INFO, "Disconnected! %d\n", handle.sock); + esl_disconnect(&handle); +} + +static esl_socket_t server_sock = ESL_SOCK_INVALID; + +static void handle_sig(int sig) +{ + shutdown(server_sock, 2); + +} + +int main(void) +{ + signal(SIGINT, handle_sig); + signal(SIGCHLD, SIG_IGN); + + esl_global_set_default_logger(7); + esl_listen("localhost", 8040, mycallback, &server_sock); + + return 0; +} From 98d453c7d908ca57ca1cd6d575d96cc0034089ce Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 14 Nov 2013 04:18:59 +0500 Subject: [PATCH 081/656] move media reset code a little deeper so it does not interrupt media when there is no change --- src/switch_core_media.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index eee0affc86..b03b90aae8 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1469,29 +1469,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine->read_impl.samples_per_packet; } } - - if (session->read_resampler) { - switch_mutex_lock(session->resample_mutex); - switch_resample_destroy(&session->read_resampler); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n"); - switch_mutex_unlock(session->resample_mutex); - } - - if (session->write_resampler) { - switch_mutex_lock(session->resample_mutex); - switch_resample_destroy(&session->write_resampler); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n"); - switch_mutex_unlock(session->resample_mutex); - } - - switch_core_session_reset(session, 0, 0); - - engine->check_frames = 0; engine->last_ts = 0; - switch_channel_audio_sync(session->channel); do_cng = 1; } @@ -1995,6 +1976,22 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_ (uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->cur_payload_map->codec_ms || a_engine->read_impl.samples_per_second != a_engine->cur_payload_map->rm_rate ) { + if (session->read_resampler) { + switch_mutex_lock(session->resample_mutex); + switch_resample_destroy(&session->read_resampler); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n"); + switch_mutex_unlock(session->resample_mutex); + } + + if (session->write_resampler) { + switch_mutex_lock(session->resample_mutex); + switch_resample_destroy(&session->write_resampler); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n"); + switch_mutex_unlock(session->resample_mutex); + } + + switch_core_session_reset(session, 0, 0); + switch_channel_audio_sync(session->channel); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz\n", From 4ee3b704960bf0064c5b89ccee0d109272bdb13b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 13 Nov 2013 17:59:52 -0600 Subject: [PATCH 082/656] fix windows esl compile --- libs/esl/src/esl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 9b62e94aa4..7a29844ab4 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -59,6 +59,7 @@ /* These warnings need to be ignored warning in sdk header */ #include #include +#include #ifndef errno #define errno WSAGetLastError() #endif @@ -1226,7 +1227,7 @@ static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t data esl_ssize_t activity = -1; if (handle->connected) { - if ((activity = esl_wait_sock(handle->sock, -1, ESL_POLL_READ|ESL_POLL_ERROR)) > 0) { + if ((activity = esl_wait_sock(handle->sock, 1000, ESL_POLL_READ|ESL_POLL_ERROR)) > 0) { if ((activity & ESL_POLL_ERROR)) { activity = -1; } else if ((activity & ESL_POLL_READ)) { From 7fb68faa559617f8dfaccc2d32ef9ce2a282ed1a Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 13 Nov 2013 18:06:12 -0600 Subject: [PATCH 083/656] fix windows build for lua 5.2 --- src/mod/languages/mod_lua/lua/lua.2012.vcxproj | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mod/languages/mod_lua/lua/lua.2012.vcxproj b/src/mod/languages/mod_lua/lua/lua.2012.vcxproj index 17f7b5eae4..ee6ce3b5d0 100644 --- a/src/mod/languages/mod_lua/lua/lua.2012.vcxproj +++ b/src/mod/languages/mod_lua/lua/lua.2012.vcxproj @@ -1,4 +1,4 @@ - + @@ -130,7 +130,10 @@ + + + @@ -161,6 +164,7 @@ + @@ -176,6 +180,7 @@ + @@ -188,4 +193,4 @@ - + \ No newline at end of file From cec4b78d53e1a49a18df7c9579967ca8cb49e3ac Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 13 Nov 2013 19:42:52 -0600 Subject: [PATCH 084/656] fix windows build for lua 5.2 VS2010 --- src/mod/languages/mod_lua/lua/lua.2010.vcxproj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mod/languages/mod_lua/lua/lua.2010.vcxproj b/src/mod/languages/mod_lua/lua/lua.2010.vcxproj index dbf8aefb92..eb3f805b97 100644 --- a/src/mod/languages/mod_lua/lua/lua.2010.vcxproj +++ b/src/mod/languages/mod_lua/lua/lua.2010.vcxproj @@ -126,7 +126,10 @@ + + + @@ -157,6 +160,7 @@ + @@ -172,6 +176,7 @@ + From 6e372418d9475ff9e639bc950bcaaa08893b54ff Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 14 Nov 2013 22:19:04 +0500 Subject: [PATCH 085/656] fix seg in new media code --- src/switch_core_media.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index b03b90aae8..7acc08cc88 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1824,7 +1824,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_get_offered_pt(switch_core_ses switch_assert(session); - if (!(smh = session->media_handle)) { + if (!(smh = session->media_handle) || !mimp) { return SWITCH_STATUS_FALSE; } @@ -3347,7 +3347,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) { - switch_core_media_get_offered_pt(session, mimp, &a_engine->cur_payload_map->recv_pt); + switch_core_media_get_offered_pt(session, matches[0].imp, &a_engine->cur_payload_map->recv_pt); } switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt); @@ -3558,7 +3558,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s pmap->recv_pt = (switch_payload_t)map->rm_pt; - if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { + if (j == 0 && (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { switch_core_media_get_offered_pt(session, mimp, &pmap->recv_pt); } } From c00b8d3fe912af783055d60b519ed045783d5962 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 14 Nov 2013 14:47:33 -0500 Subject: [PATCH 086/656] FS-5962 --resolve mod_rayo: fix unjoin request on b-leg --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 7dcd6738dc..b7158e6b1b 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -2028,7 +2028,7 @@ static iks *unjoin_call(struct rayo_call *call, switch_core_session_t *session, switch_ivr_park_session(session); } else { /* not bridged or wrong b-leg URI */ - response = iks_new_error(node, STANZA_ERROR_SERVICE_UNAVAILABLE); + response = iks_new_error_detailed_printf(node, STANZA_ERROR_SERVICE_UNAVAILABLE, "expected URI: %s", call->joined_id); } return response; @@ -2892,7 +2892,7 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev b_call = RAYO_CALL_LOCATE_BY_ID(b_uuid); if (b_call) { b_call->joined = JOINED_CALL; - b_call->joined_id = switch_core_sprintf(RAYO_POOL(b_call), "xmpp:%s@s", a_uuid, RAYO_JID(globals.server)); + b_call->joined_id = switch_core_sprintf(RAYO_POOL(b_call), "xmpp:%s@%s", a_uuid, RAYO_JID(globals.server)); /* send IQ result to client now. */ if (b_call->pending_join_request) { @@ -2906,7 +2906,7 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev /* send B-leg event */ revent = iks_new_presence("joined", RAYO_NS, RAYO_JID(b_call), rayo_call_get_dcp_jid(b_call)); joined = iks_find(revent, "joined"); - iks_insert_attrib_printf(joined, "call-uri", "xmpp:%s@%s", a_uuid, RAYO_JID(globals.server)); + iks_insert_attrib_printf(joined, "call-uri", "%s", b_call->joined_id); RAYO_SEND_MESSAGE(b_call, rayo_call_get_dcp_jid(b_call), revent); RAYO_UNLOCK(b_call); @@ -2917,7 +2917,7 @@ static void on_call_bridge_event(struct rayo_client *rclient, switch_event_t *ev switch_event_get_header(event, "variable_rayo_call_jid"), switch_event_get_header(event, "variable_rayo_dcp_jid")); joined = iks_find(revent, "joined"); - iks_insert_attrib_printf(joined, "call-uri", "xmpp:%s@%s", b_uuid, RAYO_JID(globals.server)); + iks_insert_attrib_printf(joined, "call-uri", "%s", call->joined_id); RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); From 7330b005da4ddd1dc67d6729d1e462f52238c6c5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 15 Nov 2013 01:17:22 +0500 Subject: [PATCH 087/656] codec tweak --- src/switch_core_media.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 7acc08cc88..a7feca7e4a 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1435,9 +1435,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session engine->reset_codec = 0; if (switch_rtp_ready(engine->rtp_session)) { - if (switch_core_media_set_codec(session, 1, 0) != SWITCH_STATUS_SUCCESS) { - *frame = NULL; - switch_goto_status(SWITCH_STATUS_GENERR, end); + if (type == SWITCH_MEDIA_TYPE_VIDEO) { + switch_core_media_set_video_codec(session, 1); + } else { + if (switch_core_media_set_codec(session, 1, 0) != SWITCH_STATUS_SUCCESS) { + *frame = NULL; + switch_goto_status(SWITCH_STATUS_GENERR, end); + } } if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) { @@ -3583,6 +3587,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (switch_core_media_set_video_codec(session, 0) == SWITCH_STATUS_SUCCESS) { check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, m); } + } } From cf0a3bbf835125e8d46215b1df8d06d74dc8aef8 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 14 Nov 2013 16:08:42 -0500 Subject: [PATCH 088/656] mod_rayo: added args to console aliases --- .../conf/autoload_configs/rayo.conf.xml | 12 ++-- src/mod/event_handlers/mod_rayo/mod_rayo.c | 70 ++++++++++++++++--- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index dc90b519df..9a8900dbfa 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -57,13 +57,16 @@ ]]> + ]]> ]]> ]]> - ]]> - ]]> - ]]> - ]]> + ]]> + ]]> + ]]> + ]]> + ]]> ]]> + ]]> ]]> ]]> ]]> @@ -73,6 +76,7 @@ ]]> ]]> ]]> + ]]> ]]> ]]> ]]> diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index b7158e6b1b..6d95d28885 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -3405,19 +3405,41 @@ static void on_xmpp_stream_destroy(struct xmpp_stream *stream) } } +/** + * A command alias + */ +struct rayo_cmd_alias { + /** number of additional arguments for alias */ + int args; + /** the alias template */ + const char *cmd; +}; + /** * Add an alias to an API command * @param alias_name * @param alias_target * @param alias_cmd + * @param alias_args */ -static void rayo_add_cmd_alias(const char *alias_name, const char *alias_target, const char *alias_cmd) +static void rayo_add_cmd_alias(const char *alias_name, const char *alias_target, const char *alias_cmd, const char *alias_args) { + struct rayo_cmd_alias *alias = switch_core_alloc(globals.pool, sizeof(*alias)); + alias->args = 0; + if (switch_is_number(alias_args)) { + alias->args = atoi(alias_args); + if (alias->args < 0) { + alias->args = 0; + } + } + alias->cmd = alias_cmd; + switch_core_hash_insert(globals.cmd_aliases, alias_name, alias); + + /* set up autocomplete of alias */ if (zstr(alias_target)) { alias_target = "all"; } switch_console_set_complete(switch_core_sprintf(globals.pool, "add rayo %s ::rayo::list_%s", alias_name, alias_target)); - switch_core_hash_insert(globals.cmd_aliases, alias_name, alias_cmd); } /** @@ -3614,8 +3636,9 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ for (alias = switch_xml_child(aliases, "alias"); alias; alias = alias->next) { const char *alias_name = switch_xml_attr_soft(alias, "name"); const char *alias_target = switch_xml_attr_soft(alias, "target"); + const char *alias_args = switch_xml_attr_soft(alias, "args"); if (!zstr(alias_name) && !zstr(alias->txt)) { - rayo_add_cmd_alias(alias_name, switch_core_strdup(pool, alias_target), switch_core_strdup(pool, alias->txt)); + rayo_add_cmd_alias(alias_name, switch_core_strdup(pool, alias_target), switch_core_strdup(pool, alias->txt), switch_core_strdup(pool, alias_args)); } } } @@ -3779,15 +3802,46 @@ static int command_api(char *cmd, switch_stream_handle_t *stream) /** * Send command to rayo actor */ -static int alias_api(const char *cmd, char *jid, switch_stream_handle_t *stream) +static int alias_api(struct rayo_cmd_alias *alias, char *args, switch_stream_handle_t *stream) { - if (zstr(cmd) || zstr(jid)) { - return 0; + char *argv[10] = { 0 }; + int argc, i; + char *cmd; + char *jid; + + if (zstr(alias->cmd)) { + stream->write_function(stream, "-ERR missing alias template. Check configuration.\n"); + } + + if (zstr(args)) { + stream->write_function(stream, "-ERR no args\n"); + return 1; + } + + /* check args */ + argc = switch_separate_string(args, ' ', argv, sizeof(argv) / sizeof(argv[0])); + if (argc != alias->args + 1) { + stream->write_function(stream, "-ERR wrong number of args (%i/%i)\n", argc, alias->args + 1); + return 1; + } + + jid = argv[0]; + + /* build command from args */ + cmd = strdup(alias->cmd); + for (i = 1; i < argc; i++) { + char *cmd_new; + char to_replace[4] = { 0 }; + sprintf(to_replace, "$%i", i); + cmd_new = switch_string_replace(cmd, to_replace, argv[i]); + free(cmd); + cmd = cmd_new; } /* send command */ send_console_command(globals.console, jid, cmd); stream->write_function(stream, "+OK\n"); + free(cmd); return 1; } @@ -3881,7 +3935,7 @@ static int presence_api(char *cmd, switch_stream_handle_t *stream) #define RAYO_API_SYNTAX "status | ( ) | (cmd ) | (msg ) | (presence )" SWITCH_STANDARD_API(rayo_api) { - const char *alias; + struct rayo_cmd_alias *alias; char *cmd_dup = strdup(cmd); char *argv[2] = { 0 }; int success = 0; @@ -3891,7 +3945,7 @@ SWITCH_STANDARD_API(rayo_api) /* check if a command alias */ alias = switch_core_hash_find(globals.cmd_aliases, argv[0]); - if (!zstr(alias)) { + if (alias) { success = alias_api(alias, argv[1], stream); } else if (!strcmp("cmd", argv[0])) { success = command_api(argv[1], stream); From 2906721d01e7369341b1a90ec69c65b9fa85a8b0 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 14 Nov 2013 16:11:14 -0500 Subject: [PATCH 089/656] mod_rayo: fixed config --- conf/rayo/autoload_configs/rayo.conf.xml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index 82adf96faa..9a8900dbfa 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -16,7 +16,7 @@ - + @@ -57,13 +57,16 @@ ]]> + ]]> ]]> ]]> - ]]> - ]]> - ]]> - ]]> + ]]> + ]]> + ]]> + ]]> + ]]> ]]> + ]]> ]]> ]]> ]]> @@ -73,6 +76,7 @@ ]]> ]]> ]]> + ]]> ]]> ]]> ]]> From 4fb80bf3018a4750919727641bc2623312350f58 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 15 Nov 2013 21:33:05 +0500 Subject: [PATCH 090/656] FS-5977 --resolve --- src/mod/endpoints/mod_sofia/sofia_glue.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 8c9f028348..69af0ec263 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1911,6 +1911,11 @@ int sofia_recover_callback(switch_core_session_t *session) r++; + if (profile) { + sofia_glue_release_profile(profile); + } + + return r; } From 08be6bf610a7ca487f1d1e5a5800cf1786911800 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 15 Nov 2013 21:35:06 +0500 Subject: [PATCH 091/656] FS-5971 --resolve --- src/include/switch_platform.h | 2 +- src/include/switch_version.h.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index dfd8c012bc..e0cf9cd51b 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -268,7 +268,7 @@ typedef intptr_t switch_ssize_t; #endif -#if UINTPTR_MAX == 0xffffffffffffffff +#if UINTPTR_MAX == 0xffffffffffffffff || defined(_WIN64) #define FS_64BIT 1 #endif diff --git a/src/include/switch_version.h.template b/src/include/switch_version.h.template index 06169d603f..61ebca8a98 100644 --- a/src/include/switch_version.h.template +++ b/src/include/switch_version.h.template @@ -37,7 +37,7 @@ extern "C" { #endif -#if UINTPTR_MAX == 0xffffffffffffffff +#if UINTPTR_MAX == 0xffffffffffffffff || defined(_WIN64) #define _fs__bits "64bit" #else #define _fs__bits "32bit" From 272266523734bf43c2b4cbee3e44672ff7232ed6 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Fri, 15 Nov 2013 11:21:58 -0600 Subject: [PATCH 092/656] FS-5776 --resolve Update libsoundtouch to address build issues --- src/mod/applications/mod_soundtouch/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_soundtouch/Makefile b/src/mod/applications/mod_soundtouch/Makefile index 33d3e2b227..0afa65ca69 100644 --- a/src/mod/applications/mod_soundtouch/Makefile +++ b/src/mod/applications/mod_soundtouch/Makefile @@ -1,5 +1,5 @@ BASE=../../../.. -VERSION=soundtouch-1.6.0 +VERSION=soundtouch-1.7.1 SNDT_SRC=$(switch_srcdir)/libs/soundtouch SNDT_BUILD=$(switch_builddir)/libs/soundtouch LA=$(SNDT_BUILD)/source/SoundTouch/.libs/libSoundTouch.a From e525dc38ba6073f45718ae010a7a920fd4dceecc Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 15 Nov 2013 18:44:48 +0000 Subject: [PATCH 093/656] Follow update of soundtouch version --- debian/util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/util.sh b/debian/util.sh index 7825e13d54..66231c3d82 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -101,7 +101,7 @@ getlibs () { getlib http://downloads.mongodb.org/cxx-driver/mongodb-linux-x86_64-v1.8-latest.tgz getlib http://files.freeswitch.org/downloads/libs/json-c-0.9.tar.gz getlib http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz - getlib http://files.freeswitch.org/downloads/libs/soundtouch-1.6.0.tar.gz + getlib http://files.freeswitch.org/downloads/libs/soundtouch-1.7.1.tar.gz getlib http://files.freeswitch.org/downloads/libs/flite-1.5.4-current.tar.bz2 getlib http://files.freeswitch.org/downloads/libs/sphinxbase-0.7.tar.gz getlib http://files.freeswitch.org/downloads/libs/pocketsphinx-0.7.tar.gz From f5cc10bc6b6690b6fbf73c97f68eafc09dd58d17 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Fri, 15 Nov 2013 12:58:41 -0600 Subject: [PATCH 094/656] bump libsoundtouch version in rpm spec file --- freeswitch.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freeswitch.spec b/freeswitch.spec index 1454aa6779..d1ce880237 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -118,7 +118,7 @@ Source4: http://files.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz Source5: http://files.freeswitch.org/downloads/libs/mpg123-1.13.2.tar.gz #Source6: http://files.freeswitch.org/downloads/libs/openldap-2.4.11.tar.gz Source6: http://files.freeswitch.org/downloads/libs/pocketsphinx-0.7.tar.gz -Source7: http://files.freeswitch.org/downloads/libs/soundtouch-1.6.0.tar.gz +Source7: http://files.freeswitch.org/downloads/libs/soundtouch-1.7.1.tar.gz Source8: http://files.freeswitch.org/downloads/libs/sphinxbase-0.7.tar.gz Source9: http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz Source10: http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz From b6c51a5b315fb09382118e9e5ef6d2ddd7961ccc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 16 Nov 2013 01:36:08 +0500 Subject: [PATCH 095/656] add restart-auto-record flag --- src/mod/applications/mod_conference/mod_conference.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index dd3d6bb4bb..03fd1cdfc1 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -210,7 +210,8 @@ typedef enum { CFLAG_FLOOR_CHANGE = (1 << 18), CFLAG_VID_FLOOR_LOCK = (1 << 19), CFLAG_JSON_EVENTS = (1 << 20), - CFLAG_LIVEARRAY_SYNC = (1 << 21) + CFLAG_LIVEARRAY_SYNC = (1 << 21), + CFLAG_CONF_RESTART_AUTO_RECORD = (1 << 22) } conf_flag_t; typedef enum { @@ -1457,7 +1458,7 @@ static switch_status_t conference_record_stop(conference_obj_t *conference, swit switch_mutex_lock(conference->member_mutex); for (member = conference->members; member; member = member->next) { if (switch_test_flag(member, MFLAG_NOCHANNEL) && (!path || !strcmp(path, member->rec_path))) { - if (member->rec && member->rec->autorec) { + if (!switch_test_flag(conference, CFLAG_CONF_RESTART_AUTO_RECORD) && member->rec && member->rec->autorec) { stream->write_function(stream, "Stopped AUTO recording file %s (Auto Recording Now Disabled)\n", member->rec_path); conference->auto_record = 0; } else { @@ -7695,6 +7696,8 @@ static void set_cflags(const char *flags, uint32_t *f) *f |= CFLAG_VIDEO_BRIDGE; } else if (!strcasecmp(argv[i], "audio-always")) { *f |= CFLAG_AUDIO_ALWAYS; + } else if (!strcasecmp(argv[i], "restart-auto-record")) { + *f |= CFLAG_CONF_RESTART_AUTO_RECORD; } else if (!strcasecmp(argv[i], "json-events")) { *f |= CFLAG_JSON_EVENTS; } else if (!strcasecmp(argv[i], "livearray-sync")) { From d6bb35ad3cd2dc70f170d12e7bbc0cafa4d7b417 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 16 Nov 2013 01:37:11 +0500 Subject: [PATCH 096/656] add soft timer support for fd per timer use enable-softtimer-timerfd=broadcast in switch.conf.xml for orig behaviour --- src/include/switch_core.h | 2 +- src/switch_core.c | 14 ++- src/switch_time.c | 184 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 189 insertions(+), 11 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 43c872b5cf..40f58ef26c 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2312,7 +2312,7 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload); SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token); #define switch_check_network_list_ip(_ip_str, _list_name) switch_check_network_list_ip_token(_ip_str, _list_name, NULL) SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable); -SWITCH_DECLARE(void) switch_time_set_timerfd(switch_bool_t enable); +SWITCH_DECLARE(void) switch_time_set_timerfd(int enable); SWITCH_DECLARE(void) switch_time_set_nanosleep(switch_bool_t enable); SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable); SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable); diff --git a/src/switch_core.c b/src/switch_core.c index 8cefdd2e63..848fbf2150 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1934,7 +1934,19 @@ static void switch_load_core_config(const char *file) } else if (!strcasecmp(var, "enable-monotonic-timing")) { switch_time_set_monotonic(switch_true(val)); } else if (!strcasecmp(var, "enable-softtimer-timerfd")) { - switch_time_set_timerfd(switch_true(val)); + int ival = 0; + if (val) { + if (switch_true(val)) { + ival = 2; + } else { + if (strcasecmp(val, "broadcast")) { + ival = 1; + } else if (strcasecmp(val, "fd-per-timer")) { + ival = 2; + } + } + } + switch_time_set_timerfd(ival); } else if (!strcasecmp(var, "enable-clock-nanosleep")) { switch_time_set_nanosleep(switch_true(val)); } else if (!strcasecmp(var, "enable-cond-yield")) { diff --git a/src/switch_time.c b/src/switch_time.c index 2a67a56b5e..69d45f442c 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -77,7 +77,7 @@ static int SYSTEM_TIME = 0; timerfd seems to work well as long as it exists so if you have timerfd we'll also enable clock_nanosleep by default. */ #if defined(HAVE_TIMERFD_CREATE) -static int TFD = 1; +static int TFD = 2; #if defined(HAVE_CLOCK_NANOSLEEP) static int NANO = 1; #else @@ -351,10 +351,10 @@ SWITCH_DECLARE(void) switch_time_set_use_system_time(switch_bool_t enable) } -SWITCH_DECLARE(void) switch_time_set_timerfd(switch_bool_t enable) +SWITCH_DECLARE(void) switch_time_set_timerfd(int enable) { #if defined(HAVE_TIMERFD_CREATE) - TFD = enable ? 1 : 0; + TFD = enable; switch_time_sync(); #else @@ -385,6 +385,133 @@ SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable) switch_time_sync(); } +///////// +#ifdef HAVE_TIMERFD_CREATE + +#define MAX_INTERVAL 2000 /* ms */ + +struct interval_timer { + int fd; + switch_size_t tick; +}; +typedef struct interval_timer interval_timer_t; + +static switch_status_t timerfd_start_interval(interval_timer_t *it, int interval) +{ + struct itimerspec val; + int fd; + + it->tick = 0; + + fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + + if (fd < 0) { + return SWITCH_STATUS_GENERR; + } + + val.it_interval.tv_sec = interval / 1000; + val.it_interval.tv_nsec = (interval % 1000) * 1000000; + val.it_value.tv_sec = 0; + val.it_value.tv_nsec = 100000; + + if (timerfd_settime(fd, 0, &val, NULL) < 0) { + close(fd); + return SWITCH_STATUS_GENERR; + } + + it->fd = fd; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t timerfd_stop_interval(interval_timer_t *it) +{ + close(it->fd); + it->fd = -1; + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t _timerfd_init(switch_timer_t *timer) +{ + interval_timer_t *it; + int rc; + + if (timer->interval < 1 || timer->interval > MAX_INTERVAL) + return SWITCH_STATUS_GENERR; + + it = switch_core_alloc(timer->memory_pool, sizeof(*it)); + if ((rc = timerfd_start_interval(it, timer->interval)) == SWITCH_STATUS_SUCCESS) { + timer->private_info = it; + } + + return rc; +} + +static switch_status_t _timerfd_step(switch_timer_t *timer) +{ + timer->tick++; + timer->samplecount += timer->samples; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t _timerfd_next(switch_timer_t *timer) +{ + interval_timer_t *it = timer->private_info; + uint64_t x, u64 = 0; + + if (read(it->fd, &u64, sizeof(u64)) < 0) { + return SWITCH_STATUS_GENERR; + } else { + for (x = 0; x < u64; x++) { + it->tick++; + _timerfd_step(timer); + } + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t _timerfd_sync(switch_timer_t *timer) +{ + interval_timer_t *it = timer->private_info; + + timer->tick = it->tick; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t _timerfd_check(switch_timer_t *timer, switch_bool_t step) +{ + interval_timer_t *it = timer->private_info; + int diff = (int)(timer->tick - it->tick); + + if (diff > 0) { + /* still pending */ + timer->diff = diff; + return SWITCH_STATUS_FALSE; + } else { + /* timer pending */ + timer->diff = 0; + if (step) { + _timerfd_step(timer); + } + return SWITCH_STATUS_SUCCESS; + } +} + +static switch_status_t _timerfd_destroy(switch_timer_t *timer) +{ + interval_timer_t *it = timer->private_info; + int rc; + + rc = timerfd_stop_interval(it); + return rc; +} + +#endif +//////// + + static switch_time_t time_now(int64_t offset) { switch_time_t now; @@ -549,6 +676,10 @@ static switch_status_t timer_init(switch_timer_t *timer) timer_private_t *private_info; int sanity = 0; + if (TFD == 2) { + return _timerfd_init(timer); + } + while (globals.STARTED == 0) { do_sleep(100000); if (++sanity == 300) { @@ -607,9 +738,15 @@ static switch_status_t timer_init(switch_timer_t *timer) static switch_status_t timer_step(switch_timer_t *timer) { - timer_private_t *private_info = timer->private_info; + timer_private_t *private_info; uint64_t samples; + if (TFD == 2) { + return _timerfd_step(timer); + } + + private_info = timer->private_info; + if (globals.RUNNING != 1 || private_info->ready == 0) { return SWITCH_STATUS_FALSE; } @@ -630,7 +767,13 @@ static switch_status_t timer_step(switch_timer_t *timer) static switch_status_t timer_sync(switch_timer_t *timer) { - timer_private_t *private_info = timer->private_info; + timer_private_t *private_info; + + if (TFD == 2) { + return _timerfd_sync(timer); + } + + private_info = timer->private_info; if (globals.RUNNING != 1 || private_info->ready == 0) { return SWITCH_STATUS_FALSE; @@ -648,14 +791,24 @@ static switch_status_t timer_sync(switch_timer_t *timer) static switch_status_t timer_next(switch_timer_t *timer) { - timer_private_t *private_info = timer->private_info; + timer_private_t *private_info; #ifdef DISABLE_1MS_COND int cond_index = timer->interval; #else int cond_index = 1; #endif - int delta = (int) (private_info->reference - TIMER_MATRIX[timer->interval].tick); + int delta; + + if (TFD == 2) { + return _timerfd_next(timer); + } + + private_info = timer->private_info; + + delta = (int) (private_info->reference - TIMER_MATRIX[timer->interval].tick); + + /* sync up timer if it's not been called for a while otherwise it will return instantly several times until it catches up */ if (delta < -1) { @@ -695,9 +848,15 @@ static switch_status_t timer_next(switch_timer_t *timer) static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step) { - timer_private_t *private_info = timer->private_info; + timer_private_t *private_info; switch_status_t status = SWITCH_STATUS_SUCCESS; + if (TFD == 2) { + return _timerfd_check(timer, step); + } + + private_info = timer->private_info; + if (globals.RUNNING != 1 || !private_info->ready) { return SWITCH_STATUS_SUCCESS; } @@ -724,7 +883,14 @@ static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step) static switch_status_t timer_destroy(switch_timer_t *timer) { - timer_private_t *private_info = timer->private_info; + timer_private_t *private_info; + + if (TFD == 2) { + return _timerfd_destroy(timer); + } + + private_info = timer->private_info; + if (timer->interval < MAX_ELEMENTS) { switch_mutex_lock(globals.mutex); TIMER_MATRIX[timer->interval].count--; From 34ebd6fb59181d819976af0910efbb33fa68b6c1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 16 Nov 2013 03:34:17 +0500 Subject: [PATCH 097/656] replace symbol --- src/switch_time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_time.c b/src/switch_time.c index 69d45f442c..426cba822a 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -403,7 +403,7 @@ static switch_status_t timerfd_start_interval(interval_timer_t *it, int interval it->tick = 0; - fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + fd = timerfd_create(CLOCK_MONOTONIC, 0); if (fd < 0) { return SWITCH_STATUS_GENERR; From 50857cc82d779bfa9961a5e1bf1c15a1e0d53678 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 16 Nov 2013 09:58:46 +0800 Subject: [PATCH 098/656] fix build on Mac --- src/switch_time.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/switch_time.c b/src/switch_time.c index 426cba822a..c4b6b8b445 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -676,9 +676,11 @@ static switch_status_t timer_init(switch_timer_t *timer) timer_private_t *private_info; int sanity = 0; +#ifdef HAVE_TIMERFD_CREATE if (TFD == 2) { return _timerfd_init(timer); } +#endif while (globals.STARTED == 0) { do_sleep(100000); @@ -741,9 +743,11 @@ static switch_status_t timer_step(switch_timer_t *timer) timer_private_t *private_info; uint64_t samples; +#ifdef HAVE_TIMERFD_CREATE if (TFD == 2) { return _timerfd_step(timer); } +#endif private_info = timer->private_info; @@ -769,9 +773,11 @@ static switch_status_t timer_sync(switch_timer_t *timer) { timer_private_t *private_info; +#ifdef HAVE_TIMERFD_CREATE if (TFD == 2) { return _timerfd_sync(timer); } +#endif private_info = timer->private_info; @@ -800,9 +806,11 @@ static switch_status_t timer_next(switch_timer_t *timer) #endif int delta; +#ifdef HAVE_TIMERFD_CREATE if (TFD == 2) { return _timerfd_next(timer); } +#endif private_info = timer->private_info; @@ -851,9 +859,11 @@ static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step) timer_private_t *private_info; switch_status_t status = SWITCH_STATUS_SUCCESS; +#ifdef HAVE_TIMERFD_CREATE if (TFD == 2) { return _timerfd_check(timer, step); } +#endif private_info = timer->private_info; @@ -885,9 +895,11 @@ static switch_status_t timer_destroy(switch_timer_t *timer) { timer_private_t *private_info; +#ifdef HAVE_TIMERFD_CREATE if (TFD == 2) { return _timerfd_destroy(timer); } +#endif private_info = timer->private_info; From 7256caf2784e6fa07f61a2e8fe4e0c8db27ae0a4 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 16 Nov 2013 14:17:41 +0800 Subject: [PATCH 099/656] add a debug_pool param to fsctl --- src/include/switch_core.h | 1 + src/mod/applications/mod_commands/mod_commands.c | 4 ++++ src/switch_core_session.c | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 40f58ef26c..e2c5749e7d 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2601,6 +2601,7 @@ SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_han SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream); SWITCH_DECLARE(switch_call_direction_t) switch_ice_direction(switch_core_session_t *session); +SWITCH_DECLARE(void) switch_core_session_debug_pool(switch_stream_handle_t *stream); SWITCH_END_EXTERN_C #endif diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 4a3153de5a..4ae58d2212 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2276,6 +2276,9 @@ SWITCH_STANDARD_API(ctl_function) switch_core_session_ctl(command, &arg); stream->write_function(stream, "+OK\n"); + } else if (!strcasecmp(argv[0], "debug_pool")) { + switch_core_session_debug_pool(stream); + } else if (!strcasecmp(argv[0], "debug_sql")) { int x = 0; switch_core_session_ctl(SCSC_DEBUG_SQL, &x); @@ -6535,6 +6538,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add complete del"); switch_console_set_complete("add db_cache status"); switch_console_set_complete("add fsctl debug_level"); + switch_console_set_complete("add fsctl debug_pool"); switch_console_set_complete("add fsctl debug_sql"); switch_console_set_complete("add fsctl last_sps"); switch_console_set_complete("add fsctl default_dtmf_duration"); diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 63aab9d583..0056e2d155 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -37,6 +37,8 @@ #include "switch_core.h" #include "private/switch_core_pvt.h" +#define DEBUG_THREAD_POOL + struct switch_session_manager session_manager; SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target) @@ -2984,6 +2986,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_refresh_video(switch_core_se return SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(void) switch_core_session_debug_pool(switch_stream_handle_t *stream) +{ + stream->write_function(stream, "Thread pool: running:%d busy:%d popping:%d\n", + session_manager.running, session_manager.busy, session_manager.popping); +} /* For Emacs: * Local Variables: From 8f51875e3e2d0e18326472c16e7c617387051ef3 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sat, 16 Nov 2013 11:32:36 -0600 Subject: [PATCH 100/656] FS-5971 fix conditional compile for for windows x64 --- src/include/switch_platform.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index e0cf9cd51b..7efd84eaa8 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -227,9 +227,10 @@ typedef intptr_t switch_ssize_t; #ifdef WIN32 -#ifdef WIN64 +#ifdef _WIN64 #define SWITCH_SSIZE_T_FMT "lld" #define SWITCH_SIZE_T_FMT "lld" +#define FS_64BIT 1 #else #define SWITCH_SSIZE_T_FMT "d" #define SWITCH_SIZE_T_FMT "d" @@ -268,7 +269,7 @@ typedef intptr_t switch_ssize_t; #endif -#if UINTPTR_MAX == 0xffffffffffffffff || defined(_WIN64) +#if UINTPTR_MAX == 0xffffffffffffffff #define FS_64BIT 1 #endif From 49f9bd01bfb0614787f76fed29ea8a06e2c13a12 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 17 Nov 2013 06:51:33 +0500 Subject: [PATCH 101/656] fix some contention in rtmp --- src/mod/endpoints/mod_rtmp/mod_rtmp.c | 146 +++++++++++++++++++------- src/mod/endpoints/mod_rtmp/mod_rtmp.h | 2 + 2 files changed, 111 insertions(+), 37 deletions(-) diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.c b/src/mod/endpoints/mod_rtmp/mod_rtmp.c index e25f38b861..4e6e10db8f 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.c +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.c @@ -40,7 +40,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rtmp_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rtmp_shutdown); -SWITCH_MODULE_DEFINITION(mod_rtmp, mod_rtmp_load, mod_rtmp_shutdown, NULL); +SWITCH_MODULE_RUNTIME_FUNCTION(mod_rtmp_runtime); +SWITCH_MODULE_DEFINITION(mod_rtmp, mod_rtmp_load, mod_rtmp_shutdown, mod_rtmp_runtime); static switch_status_t config_profile(rtmp_profile_t *profile, switch_bool_t reload); static switch_xml_config_item_t *get_instructions(rtmp_profile_t *profile); @@ -732,7 +733,7 @@ rtmp_session_t *rtmp_session_locate(const char *uuid) { rtmp_session_t *rsession = switch_core_hash_find_rdlock(rtmp_globals.session_hash, uuid, rtmp_globals.session_rwlock); - if (!rsession || rsession->state == RS_DESTROY) { + if (!rsession || rsession->state >= RS_DESTROY) { return NULL; } @@ -812,53 +813,95 @@ switch_status_t rtmp_session_request(rtmp_profile_t *profile, rtmp_session_t **n return SWITCH_STATUS_SUCCESS; } +static void rtmp_garbage_colletor(void) +{ + switch_hash_index_t *hi; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RTMP Garbage Collection\n"); + + + switch_thread_rwlock_wrlock(rtmp_globals.session_rwlock); + + top: + + for (hi = switch_hash_first(NULL, rtmp_globals.session_hash); hi; hi = switch_hash_next(hi)) { + void *val; + const void *key; + switch_ssize_t keylen; + rtmp_session_t *rsession; + + switch_hash_this(hi, &key, &keylen, &val); + rsession = (rtmp_session_t *) val; + + if (rsession->state == RS_DESTROY) { + if (rtmp_real_session_destroy(&rsession) == SWITCH_STATUS_SUCCESS) { + goto top; + } + } + } + + switch_thread_rwlock_unlock(rtmp_globals.session_rwlock); +} + switch_status_t rtmp_session_destroy(rtmp_session_t **rsession) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_mutex_lock(rtmp_globals.mutex); + if (rsession && *rsession) { + (*rsession)->state = RS_DESTROY; + *rsession = NULL; + status = SWITCH_STATUS_SUCCESS; + } + switch_mutex_unlock(rtmp_globals.mutex); + + return status; +} + +switch_status_t rtmp_real_session_destroy(rtmp_session_t **rsession) { switch_hash_index_t *hi; switch_event_t *event; - - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, RTMP_EVENT_DISCONNECT) == SWITCH_STATUS_SUCCESS) { - rtmp_event_fill(*rsession, event); - switch_event_fire(&event); - } - - switch_core_hash_delete_wrlock(rtmp_globals.session_hash, (*rsession)->uuid, rtmp_globals.session_rwlock); - switch_core_hash_delete_wrlock((*rsession)->profile->session_hash, (*rsession)->uuid, (*rsession)->profile->session_rwlock); - rtmp_clear_registration(*rsession, NULL, NULL); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "RTMP session ended [%s]\n", (*rsession)->uuid); - - (*rsession)->state = RS_DESTROY; + int sess = 0; switch_thread_rwlock_rdlock((*rsession)->session_rwlock); for (hi = switch_hash_first(NULL, (*rsession)->session_hash); hi; hi = switch_hash_next(hi)) { void *val; const void *key; switch_ssize_t keylen; - rtmp_private_t *tech_pvt; switch_channel_t *channel; switch_core_session_t *session; - switch_hash_this(hi, &key, &keylen, &val); - tech_pvt = (rtmp_private_t *)val; - - /* At this point we don't know if the session still exists, so request a fresh pointer to it from the core. */ - if ( (session = switch_core_session_locate((char *)key)) != NULL ) { - /* - * This is here so that if the FS session still exists and has the FS session write(or read) lock, then we won't destroy the rsession - * until the FS session is finished with it. But if the rsession is able to get the FS session - * write lock, before the FS session is hungup, then once the FS session does get the write lock - * the rsession pointer will be null, and the FS session will never try and touch the already destroyed rsession. - */ + switch_hash_this(hi, &key, &keylen, &val); + + /* If there are any sessions attached, abort the destroy operation */ + if ((session = switch_core_session_locate((char *)key)) != NULL ) { channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); - if ( tech_pvt && tech_pvt->rtmp_session ) { - tech_pvt->rtmp_session = NULL; - } switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_core_session_rwunlock(session); + sess++; } } switch_thread_rwlock_unlock((*rsession)->session_rwlock); + + if (sess) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RTMP session [%s] %p still busy.\n", (*rsession)->uuid, (void *) *rsession); + return SWITCH_STATUS_FALSE; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RTMP session [%s] %p will be destroyed.\n", (*rsession)->uuid, (void *) *rsession); + + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, RTMP_EVENT_DISCONNECT) == SWITCH_STATUS_SUCCESS) { + rtmp_event_fill(*rsession, event); + switch_event_fire(&event); + } + + switch_core_hash_delete(rtmp_globals.session_hash, (*rsession)->uuid); + switch_core_hash_delete_wrlock((*rsession)->profile->session_hash, (*rsession)->uuid, (*rsession)->profile->session_rwlock); + rtmp_clear_registration(*rsession, NULL, NULL); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "RTMP session ended [%s]\n", (*rsession)->uuid); + switch_mutex_lock((*rsession)->profile->mutex); if ( (*rsession)->profile->calls < 1 ) { @@ -1137,7 +1180,7 @@ static void rtmp_clear_reg_auth(rtmp_session_t *rsession, const char *auth, cons switch_thread_rwlock_wrlock(rsession->profile->reg_rwlock); if ((reg = switch_core_hash_find(rsession->profile->reg_hash, auth))) { for (; reg; reg = reg->next) { - if (!strcmp(reg->uuid, rsession->uuid) && (zstr(nickname) || !strcmp(reg->nickname, nickname))) { + if (!zstr(reg->uuid) && !strcmp(reg->uuid, rsession->uuid) && (zstr(nickname) || !strcmp(reg->nickname, nickname))) { switch_event_t *event; if (prev) { prev->next = reg->next; @@ -1495,6 +1538,20 @@ done: return SWITCH_STATUS_SUCCESS; } +static const char *state2name(int state) +{ + switch(state) { + case RS_HANDSHAKE: + return "HANDSHAKE"; + case RS_HANDSHAKE2: + return "HANDSHAKE2"; + case RS_ESTABLISHED: + return "ESTABLISHED"; + default: + return "DESTROY (PENDING)"; + } +} + #define RTMP_FUNCTION_SYNTAX "profile [profilename] [start | stop | rescan | restart]\nstatus profile [profilename]\nstatus profile [profilename] [reg | sessions]\nsession [session_id] [kill | login [user@domain] | logout [user@domain]]" SWITCH_STANDARD_API(rtmp_function) { @@ -1571,7 +1628,7 @@ SWITCH_STANDARD_API(rtmp_function) { switch_hash_index_t *hi; stream->write_function(stream, "\nSessions:\n"); - stream->write_function(stream, "uuid,address,user,domain,flashVer\n"); + stream->write_function(stream, "uuid,address,user,domain,flashVer,state\n"); switch_thread_rwlock_rdlock(profile->session_rwlock); for (hi = switch_hash_first(NULL, profile->session_hash); hi; hi = switch_hash_next(hi)) { void *val; @@ -1581,11 +1638,11 @@ SWITCH_STANDARD_API(rtmp_function) switch_hash_this(hi, &key, &keylen, &val); item = (rtmp_session_t *)val; - stream->write_function(stream, "%s,%s:%d,%s,%s,%s\n", - item->uuid, item->remote_address, item->remote_port, - item->account ? item->account->user : NULL, - item->account ? item->account->domain : NULL, - item->flashVer); + stream->write_function(stream, "%s,%s:%d,%s,%s,%s,%s\n", + item->uuid, item->remote_address, item->remote_port, + item->account ? item->account->user : NULL, + item->account ? item->account->domain : NULL, + item->flashVer, state2name(item->state)); } switch_thread_rwlock_unlock(profile->session_rwlock); @@ -1862,6 +1919,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rtmp_load) switch_xml_free(xml); } } + + rtmp_globals.running = 1; return SWITCH_STATUS_SUCCESS; } @@ -1892,9 +1951,22 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rtmp_shutdown) switch_core_hash_destroy(&rtmp_globals.session_hash); switch_core_hash_destroy(&rtmp_globals.invoke_hash); + rtmp_globals.running = 0; + return SWITCH_STATUS_SUCCESS; } +SWITCH_MODULE_RUNTIME_FUNCTION(mod_rtmp_runtime) +{ + + while(rtmp_globals.running) { + rtmp_garbage_colletor(); + switch_yield(10000000); + } + + return SWITCH_STATUS_TERM; +} + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.h b/src/mod/endpoints/mod_rtmp/mod_rtmp.h index 8a92c5b427..95eb17f017 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.h +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.h @@ -336,6 +336,7 @@ struct mod_rtmp_globals { switch_hash_t *session_hash; switch_thread_rwlock_t *session_rwlock; switch_hash_t *invoke_hash; + int running; }; extern struct mod_rtmp_globals rtmp_globals; @@ -605,6 +606,7 @@ void rtmp_profile_release(rtmp_profile_t *profile); switch_status_t rtmp_tcp_init(rtmp_profile_t *profile, const char *bindaddr, rtmp_io_t **new_io, switch_memory_pool_t *pool); switch_status_t rtmp_session_request(rtmp_profile_t *profile, rtmp_session_t **newsession); switch_status_t rtmp_session_destroy(rtmp_session_t **session); +switch_status_t rtmp_real_session_destroy(rtmp_session_t **session); /**** Protocol ****/ void rtmp_set_chunksize(rtmp_session_t *rsession, uint32_t chunksize); From f9a532900b0bd0cffccb89bd6b4cc743007215bc Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sun, 17 Nov 2013 20:55:38 +0800 Subject: [PATCH 102/656] add total used count for debug --- src/switch_core_sqldb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 0b4d8b9ede..c53fc75a40 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -52,6 +52,7 @@ struct switch_cache_db_handle { char creator[CACHE_DB_LEN]; char last_user[CACHE_DB_LEN]; uint32_t use_count; + uint64_t total_used_count; struct switch_cache_db_handle *next; }; @@ -102,6 +103,7 @@ static void add_handle(switch_cache_db_handle_t *dbh, const char *db_str, const dbh->thread_hash = switch_ci_hashfunc_default(thread_str, &hlen); dbh->use_count++; + dbh->total_used_count++; sql_manager.total_used_handles++; dbh->next = sql_manager.handle_pool; @@ -149,7 +151,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user r = dbh_ptr; } } - + if (!r) { for (dbh_ptr = sql_manager.handle_pool; dbh_ptr; dbh_ptr = dbh_ptr->next) { if (dbh_ptr->hash == hash && (dbh_ptr->type != SCDB_TYPE_PGSQL || !dbh_ptr->use_count) && !switch_test_flag(dbh_ptr, CDF_PRUNE) && @@ -162,6 +164,7 @@ static switch_cache_db_handle_t *get_handle(const char *db_str, const char *user if (r) { r->use_count++; + r->total_used_count++; sql_manager.total_used_handles++; r->hash = switch_ci_hashfunc_default(db_str, &hlen); r->thread_hash = thread_hash; @@ -3510,11 +3513,12 @@ SWITCH_DECLARE(void) switch_cache_db_status(switch_stream_handle_t *stream) used++; } - stream->write_function(stream, "%s\n\tType: %s\n\tLast used: %d\n\tFlags: %s, %s(%d)\n" + stream->write_function(stream, "%s\n\tType: %s\n\tLast used: %d\n\tTotal used: %ld\n\tFlags: %s, %s(%d)\n" "\tCreator: %s\n\tLast User: %s\n", cleankey_str, switch_cache_db_type_name(dbh->type), diff, + dbh->total_used_count, locked ? "Locked" : "Unlocked", dbh->use_count ? "Attached" : "Detached", dbh->use_count, dbh->creator, dbh->last_user); } From dd67bd41f9e3bc050d465d937ff6843a609e791d Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sun, 17 Nov 2013 21:18:06 +0800 Subject: [PATCH 103/656] do not treat key exists as error as already doing in other place --- src/switch_pgsql.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index 9917ea2653..20fe886193 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -461,7 +461,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const cha int done = 0; do { switch_pgsql_next_result(handle, &res); - if (res && res->err) { + if (res && res->err && !switch_stristr("already exists", res->err) && !switch_stristr("duplicate key name", res->err)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error executing query:\n%s\n", res->err); final_status = SWITCH_PGSQL_FAIL; } From 46f505591455a8f0967c81c92b48f66ced710535 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Mon, 18 Nov 2013 15:10:51 +0800 Subject: [PATCH 104/656] avoid loop and adding a missing complete --- src/mod/applications/mod_commands/mod_commands.c | 3 ++- src/switch_console.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 4ae58d2212..019e3f8563 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -34,7 +34,7 @@ * Rupa Schomaker * Joseph Sullivan * Raymond Chandler - * + * Seven Du * Garmt Boekholt * * mod_commands.c -- Misc. Command Module @@ -6532,6 +6532,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add alias add"); + switch_console_set_complete("add alias stickyadd"); switch_console_set_complete("add alias del"); switch_console_set_complete("add coalesce"); switch_console_set_complete("add complete add"); diff --git a/src/switch_console.c b/src/switch_console.c index 63fe575856..d43f7702e1 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -1921,6 +1921,11 @@ SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string) switch_cache_db_handle_t *db = NULL; char *sql = NULL; + if (!strcmp(argv[1], argv[2])) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Alias and command cannot be the same, this will cause loop!\n"); + return SWITCH_STATUS_FALSE; + } + if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database Error\n"); free(mydata); From f14260e8dd451fe66f0dce35f87962d1aa149ff7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 19 Nov 2013 00:43:30 +0500 Subject: [PATCH 105/656] set fmtp in payload_map init function --- src/include/switch_core_media.h | 1 + src/switch_core_media.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index cfbe9921eb..6391df0aaf 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -315,6 +315,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session, switch_media_type_t type, const char *name, + const char *fmtp, switch_sdp_type_t sdp_type, uint32_t pt, uint32_t rate, diff --git a/src/switch_core_media.c b/src/switch_core_media.c index a7feca7e4a..5922433ec6 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -511,6 +511,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session, switch_media_type_t type, const char *name, + const char *fmtp, switch_sdp_type_t sdp_type, uint32_t pt, uint32_t rate, @@ -567,6 +568,10 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se pmap->rate = rate; } + if (!zstr(fmtp) && (!pmap->rm_fmtp || strcmp(pmap->rm_fmtp, fmtp))) { + pmap->rm_fmtp = switch_core_strdup(session->pool, fmtp); + } + pmap->allocated = 1; pmap->recv_pt = (switch_payload_t)pt; @@ -3285,7 +3290,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s for(j = 0; j < m_idx; j++) { payload_map_t *pmap = switch_core_media_add_payload_map(session, SWITCH_MEDIA_TYPE_AUDIO, - matches[j].map->rm_encoding, + matches[j].map->rm_encoding, + matches[j].map->rm_fmtp, sdp_type, matches[j].map->rm_pt, matches[j].imp->samples_per_second, @@ -3534,6 +3540,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s payload_map_t *pmap = switch_core_media_add_payload_map(session, SWITCH_MEDIA_TYPE_VIDEO, matches[j].map->rm_encoding, + matches[j].map->rm_fmtp, sdp_type, matches[j].map->rm_pt, matches[j].imp->samples_per_second, @@ -5806,6 +5813,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_core_media_add_payload_map(session, imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, imp->iananame, + NULL, sdp_type, smh->ianacodes[i], imp->samples_per_second, @@ -7868,6 +7876,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess switch_core_media_add_payload_map(session, m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, map->rm_encoding, + map->rm_fmtp, sdp_type, map->rm_pt, map->rm_rate, From 714eb245fdfefc8a4f40dca4ec95f06e76d2bd15 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 19 Nov 2013 15:19:06 -0600 Subject: [PATCH 106/656] remove unused code --- src/switch_core_media.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 5922433ec6..9911cad4c1 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3038,43 +3038,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } x = 0; - - if (a_engine->cur_payload_map->rm_encoding && !(switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || - switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) { // && !switch_channel_test_flag(session->channel, CF_REINVITE)) { - char *remote_host = a_engine->cur_payload_map->remote_sdp_ip; - switch_port_t remote_port = a_engine->cur_payload_map->remote_sdp_port; - int same = 0; - - if (switch_rtp_ready(a_engine->rtp_session)) { - remote_host = switch_rtp_get_remote_host(a_engine->rtp_session); - remote_port = switch_rtp_get_remote_port(a_engine->rtp_session); - } - - for (map = m->m_rtpmaps; map; map = map->rm_next) { - if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { - match = (map->rm_pt == a_engine->cur_payload_map->pt) ? 1 : 0; - } else { - match = strcasecmp(switch_str_nil(map->rm_encoding), a_engine->cur_payload_map->iananame) ? 0 : 1; - } - - if (match && connection->c_address && remote_host && !strcmp(connection->c_address, remote_host) && m->m_port == remote_port) { - same = 1; - } else { - same = 0; - break; - } - } - - if (same) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, - "Our existing sdp is still good [%s %s:%d], let's keep it.\n", - a_engine->cur_payload_map->rm_encoding, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port); - got_audio = 1; - } else { - match = 0; - got_audio = 0; - } - } for (map = m->m_rtpmaps; map; map = map->rm_next) { int32_t i; From 75481f6398efc1c1b1bfac86d7b62e7fbc549d36 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 19 Nov 2013 21:06:41 +0000 Subject: [PATCH 107/656] Refactor out file merge function --- debian/bootstrap.sh | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 03953b36c0..27841ff2e3 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -1142,6 +1142,18 @@ set_modules_non_dfsg () { done } +conf_merge () { + local of="$1" if="$2" + if [ -s $if ]; then + grep -v '^##\|^$' $if | while xread x; do + touch $of + if ! grep -e "$x" $of >/dev/null; then + printf '%s\n' "$x" >> $of + fi + done + fi +} + codename="sid" modulelist_opt="" while getopts "c:m:" o; do @@ -1194,14 +1206,7 @@ map_modules "mod_filter" \ echo "Generating debian/ (-all package)..." >&2 grep -e '^Package:' control | grep -v '^freeswitch-all$' | while xread l; do m="${l#*: }" - f=$m.install - if [ -s $f ]; then - grep -v '^##\|^$' $f | while xread x; do - if ! grep -e "$x" freeswitch-all.install >/dev/null; then - printf '%s\n' "$x" >> freeswitch-all.install - fi - done - fi + conf_merge freeswitch-all.install $m.install done for x in postinst postrm preinst prerm; do cp -a freeswitch.$x freeswitch-all.$x From ce690418a109df333caeefc1c50992731e6988e3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 20 Nov 2013 03:36:45 +0500 Subject: [PATCH 108/656] FS-5959 add rtp_mirror_fmtp var --- src/switch_core_media.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 9911cad4c1..9939ce7712 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6293,9 +6293,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (ov_fmtp) { pass_fmtp = ov_fmtp; - }// else { // seems to break eyebeam at least... - //pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp"); - //} + } else if (switch_true(switch_channel_get_variable_dup(session->channel, "rtp_mirror_fmtp", SWITCH_FALSE, -1))) { + // seems to break eyebeam at least... + pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp"); + } } if (pass_fmtp) { From 0030ce440ebd7168d053e67f6457267e5d0c298f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 20 Nov 2013 05:20:01 +0500 Subject: [PATCH 109/656] FS-5958 this should pass it through in late mode too --- src/include/switch_core_media.h | 3 ++- src/switch_core_media.c | 30 ++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 6391df0aaf..d827385d62 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -310,7 +310,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core switch_media_type_t type, const char *iananame, switch_payload_t *ptP, - switch_payload_t *recv_ptP); + switch_payload_t *recv_ptP, + char **fmtpP); SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_session_t *session, switch_media_type_t type, diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 9939ce7712..426334466a 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -167,6 +167,7 @@ struct switch_media_handle_s { const switch_codec_implementation_t *negotiated_codecs[SWITCH_MAX_CODECS]; int num_negotiated_codecs; switch_payload_t ianacodes[SWITCH_MAX_CODECS]; + char *fmtps[SWITCH_MAX_CODECS]; int video_count; uint32_t owner_id; @@ -464,13 +465,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core switch_media_type_t type, const char *iananame, switch_payload_t *ptP, - switch_payload_t *recv_ptP) + switch_payload_t *recv_ptP, + char **fmtpP) { payload_map_t *pmap; switch_media_handle_t *smh; switch_rtp_engine_t *engine; switch_payload_t pt = 0, recv_pt = 0; int found = 0; + char *fmtp = NULL; switch_assert(session); @@ -488,6 +491,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core if (!strcasecmp(pmap->iananame, iananame)) { pt = pmap->pt; recv_pt = pmap->recv_pt; + fmtp = pmap->rm_fmtp; found++; } } @@ -500,6 +504,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core if (recv_ptP) { *recv_ptP = recv_pt; } + + if (!zstr(fmtp) && fmtpP) { + *fmtpP = fmtp; + } + return SWITCH_STATUS_SUCCESS; } @@ -5391,6 +5400,10 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, } } + if (smh->fmtps[i]) { + fmtp = smh->fmtps[i]; + } + if (smh->ianacodes[i] > 95 || switch_channel_test_flag(session->channel, CF_VERBOSE_SDP)) { int channels = get_channels(imp->iananame, imp->number_of_channels); @@ -5665,7 +5678,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess const char *fmtp_out; const char *fmtp_out_var = switch_channel_get_variable(session->channel, "rtp_force_audio_fmtp"); switch_event_t *map = NULL, *ptmap = NULL; - const char *b_sdp = NULL; + //const char *b_sdp = NULL; const char *local_audio_crypto_key = switch_core_session_local_crypto_key(session, SWITCH_MEDIA_TYPE_AUDIO); const char *local_sdp_audio_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_TRUE); const char *local_sdp_video_zrtp_hash = switch_core_media_get_zrtp_hash(session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_TRUE); @@ -5750,6 +5763,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess for (i = 0; i < smh->mparams->num_codecs; i++) { const switch_codec_implementation_t *imp = smh->codecs[i]; switch_payload_t orig_pt = 0; + char *orig_fmtp = NULL; smh->ianacodes[i] = imp->ianacode; @@ -5765,8 +5779,12 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (orig_session && switch_core_session_get_payload_code(orig_session, imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, - imp->iananame, &orig_pt, NULL) == SWITCH_STATUS_SUCCESS) { + imp->iananame, &orig_pt, NULL, &orig_fmtp) == SWITCH_STATUS_SUCCESS) { smh->ianacodes[i] = orig_pt; + + if (orig_fmtp) { + smh->fmtps[i] = switch_core_session_strdup(session, orig_fmtp); + } } else { smh->ianacodes[i] = (switch_payload_t)smh->payload_space++; } @@ -5829,9 +5847,9 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess return; } - if (!a_engine->cur_payload_map->rm_encoding && (b_sdp = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) { - switch_core_media_sdp_map(b_sdp, &map, &ptmap); - } + //if (!a_engine->cur_payload_map->rm_encoding && (b_sdp = switch_channel_get_variable(session->channel, SWITCH_B_SDP_VARIABLE))) { + //switch_core_media_sdp_map(b_sdp, &map, &ptmap); + //} if (zstr(sr)) { if ((var_val = switch_channel_get_variable(session->channel, "media_audio_mode"))) { From 9268f2403171b506d34f9eb140cb731dcb9203ef Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 19 Nov 2013 21:59:53 +0000 Subject: [PATCH 110/656] Refactor generation of debian/modules_.conf --- debian/bootstrap.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 27841ff2e3..dedf5e92cb 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -937,12 +937,11 @@ genoverrides_per_mod () { test -f $f.tmpl && cat $f.tmpl >> $f } -genmodules_per_cat () { - echo "## $category" >> modules_.conf -} - -genmodules_per_mod () { - echo "$module" >> modules_.conf +genmodulesconf () { + genmodules_per_cat () { echo "## $category"; } + genmodules_per_mod () { echo "$module"; } + print_edit_warning + map_modules 'mod_filter' 'genmodules_per_cat' 'genmodules_per_mod' } genconf () { @@ -1199,10 +1198,10 @@ echo "Generating debian/ (lang)..." >&2 map_langs 'genlang' echo "Generating debian/ (modules)..." >&2 (echo "### modules"; echo) >> control -print_edit_warning > modules_.conf +genmodulesconf > modules_.conf map_modules "mod_filter" \ - "gencontrol_per_cat genmodules_per_cat" \ - "gencontrol_per_mod geninstall_per_mod genoverrides_per_mod genmodules_per_mod" + "gencontrol_per_cat" \ + "gencontrol_per_mod geninstall_per_mod genoverrides_per_mod" echo "Generating debian/ (-all package)..." >&2 grep -e '^Package:' control | grep -v '^freeswitch-all$' | while xread l; do m="${l#*: }" From 7a77d2f3fed1b670d0d1f871993477e215616c52 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 19 Nov 2013 22:03:00 +0000 Subject: [PATCH 111/656] Generate modules_.conf earlier in bootstrap --- debian/bootstrap.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index dedf5e92cb..edfe7f1077 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -1176,6 +1176,8 @@ echo "Parsing control-modules..." >&2 parse_mod_control echo "Displaying includes/excludes..." >&2 map_modules 'mod_filter_show' '' '' +echo "Generating modules_.conf..." >&2 +genmodulesconf > modules_.conf echo "Generating control-modules.gen as sanity check..." >&2 (echo "# -*- mode:debian-control -*-"; \ echo "##### Author: Travis Cross "; echo; \ @@ -1198,7 +1200,6 @@ echo "Generating debian/ (lang)..." >&2 map_langs 'genlang' echo "Generating debian/ (modules)..." >&2 (echo "### modules"; echo) >> control -genmodulesconf > modules_.conf map_modules "mod_filter" \ "gencontrol_per_cat" \ "gencontrol_per_mod geninstall_per_mod genoverrides_per_mod" From fc5557b949a2493877c768dcc8c2fe1f3346ce73 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 20 Nov 2013 07:36:20 -0600 Subject: [PATCH 112/656] FS-5986 --resolve fix download reference to windows libcelt --- libs/win32/celt/libcelt.2012.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/win32/celt/libcelt.2012.vcxproj b/libs/win32/celt/libcelt.2012.vcxproj index 3661a6f4f2..5653c61be6 100644 --- a/libs/win32/celt/libcelt.2012.vcxproj +++ b/libs/win32/celt/libcelt.2012.vcxproj @@ -142,7 +142,7 @@ - + {fff82f9b-6a2b-4be3-95d8-dc5a4fc71e19} false From 8c035205028ebd1e2807f3cf26f47e397b0e0ddf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 20 Nov 2013 22:00:29 +0500 Subject: [PATCH 113/656] FS-5959 --- src/switch_core_media.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 426334466a..b3d4e76eff 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -544,9 +544,17 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { - exists = (!strcasecmp(name, pmap->iananame) && (!pmap->rate || rate == pmap->rate) && (pmap->ptime || pmap->ptime == ptime)); + exists = (!strcasecmp(name, pmap->iananame) && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime)); if (exists) { + + if (!zstr(fmtp) && !zstr(pmap->rm_fmtp)) { + if (strcmp(pmap->rm_fmtp, fmtp)) { + exists = 0; + continue; + } + } + break; } } @@ -3487,7 +3495,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s matches[m_idx].imp = imp; matches[m_idx].map = map; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] is saved as a match\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] +++ is saved as a match\n", imp->iananame, imp->ianacode); m_idx++; } From 51464b7b8cbac4f4d2399342a65fe31f539270e7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 20 Nov 2013 23:49:18 +0500 Subject: [PATCH 114/656] FS-5959 always do rtp_mirror_fmtp behaviour --- src/switch_core_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index b3d4e76eff..5a0bff64db 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6319,7 +6319,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (ov_fmtp) { pass_fmtp = ov_fmtp; - } else if (switch_true(switch_channel_get_variable_dup(session->channel, "rtp_mirror_fmtp", SWITCH_FALSE, -1))) { + } else { //if (switch_true(switch_channel_get_variable_dup(session->channel, "rtp_mirror_fmtp", SWITCH_FALSE, -1))) { // seems to break eyebeam at least... pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp"); } From 2f1c82ff363bd42cfa646b7b61f059f20cf6b68c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 20 Nov 2013 23:49:44 +0500 Subject: [PATCH 115/656] FS-5959 set floor when turning on video mid call in conference --- src/mod/applications/mod_conference/mod_conference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 03fd1cdfc1..1564b1898d 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -3650,6 +3650,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v switch_set_flag_locked(member, MFLAG_ACK_VIDEO); switch_channel_clear_flag(channel, CF_VIDEO_ECHO); switch_core_session_refresh_video(member->session); + conference_set_video_floor_holder(member->conference, member, SWITCH_FALSE); } /* if we have caller digits, feed them to the parser to find an action */ From 634d936a027664b6e0d1cb46f71e0070f5f5a9bc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 20 Nov 2013 23:50:15 +0500 Subject: [PATCH 116/656] kill socket in esl_disconnect to prevent blocking --- libs/esl/src/esl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 7a29844ab4..67b82fbe6d 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -1123,6 +1123,12 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle) return ESL_FAIL; } + if (handle->sock != ESL_SOCK_INVALID) { + closesocket(handle->sock); + handle->sock = ESL_SOCK_INVALID; + status = ESL_SUCCESS; + } + if (mutex) { esl_mutex_lock(mutex); } @@ -1145,12 +1151,6 @@ ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle) esl_event_safe_destroy(&handle->last_ievent); esl_event_safe_destroy(&handle->info_event); - if (handle->sock != ESL_SOCK_INVALID) { - closesocket(handle->sock); - handle->sock = ESL_SOCK_INVALID; - status = ESL_SUCCESS; - } - if (mutex) { esl_mutex_unlock(mutex); esl_mutex_lock(mutex); From 20038230d47552f928664ae211804eeb7045ba04 Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 20 Nov 2013 11:12:48 -0800 Subject: [PATCH 117/656] This was in the wrong section. Should be setting it on the auth_invite, not the auth_registration. --- src/mod/xml_int/mod_xml_radius/mod_xml_radius.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c index af3bb638f8..6695e21382 100644 --- a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c +++ b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c @@ -666,6 +666,10 @@ switch_xml_t mod_xml_radius_auth_invite(switch_event_t *params) { switch_xml_set_attr_d(usr, "id", switch_event_get_header(params, "user")); + var = switch_xml_add_child_d(vars, "variable", param_idx++); + switch_xml_set_attr_d(var, "name", "radius_auth_result"); + switch_xml_set_attr_d(var, "value", "0"); + service_vp = recv; while (service_vp != NULL) { rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512); @@ -774,10 +778,6 @@ switch_xml_t mod_xml_radius_auth_reg(switch_event_t *params) { switch_xml_set_attr_d(usr, "id", switch_event_get_header(params, "user")); - var = switch_xml_add_child_d(vars, "variable", param_idx++); - switch_xml_set_attr_d(var, "name", "radius_auth_result"); - switch_xml_set_attr_d(var, "value", "0"); - service_vp = recv; while (service_vp != NULL) { rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512); From ccaa3ae7326e752212fc9c52576859c2dc8d2c23 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 21 Nov 2013 01:38:16 +0500 Subject: [PATCH 118/656] FS-5959 --- src/include/switch_types.h | 2 ++ src/mod/endpoints/mod_sofia/mod_sofia.c | 12 ++++---- src/switch_core_media.c | 37 ++++++++++++++++++++++--- src/switch_rtp.c | 15 ++++++---- 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 8d042eae11..0567fd2455 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -668,6 +668,8 @@ typedef enum { SWITCH_RTP_FLAG_KILL_JB, SWITCH_RTP_FLAG_VIDEO_BREAK, SWITCH_RTP_FLAG_PAUSE, + SWITCH_RTP_FLAG_FIR, + SWITCH_RTP_FLAG_PLI, SWITCH_RTP_FLAG_INVALID } switch_rtp_flag_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index dc6351799d..5e27ccc864 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1245,19 +1245,19 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ: { - const char *pl = ""; - time_t now = switch_epoch_time_now(NULL); + const char *pl = "\n\n\n\n\n\n\n\n"; + //time_t now = switch_epoch_time_now(NULL); - if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 5) { - - tech_pvt->last_vid_info = now; + //if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 5) { + + // tech_pvt->last_vid_info = now; if (!zstr(msg->string_arg)) { pl = msg->string_arg; } nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); - } + //} } break; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 5a0bff64db..fdb4043f54 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -144,6 +144,10 @@ typedef struct switch_rtp_engine_s { uint8_t reset_codec; uint8_t codec_negotiated; + + uint8_t fir; + uint8_t pli; + } switch_rtp_engine_t; @@ -3435,8 +3439,19 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s for (attr = m->m_attributes; attr; attr = attr->a_next) { if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) { //framerate = atoi(attr->a_value); - } - if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value && !strcmp(attr->a_value, "1")) { + } else if (!strcasecmp(attr->a_name, "rtcp-fb")) { + if (!zstr(attr->a_value)) { + if (switch_stristr("fir", attr->a_value)) { + v_engine->fir++; + } + + if (switch_stristr("pli", attr->a_value)) { + v_engine->pli++; + } + + smh->mparams->rtcp_video_interval_msec = "10000"; + } + } else if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value && !strcmp(attr->a_value, "1")) { switch_channel_set_variable(session->channel, "rtp_remote_video_rtcp_port", attr->a_value); v_engine->remote_rtcp_port = (switch_port_t)atoi(attr->a_value); } else if (!got_video_crypto && !strcasecmp(attr->a_name, "crypto") && !zstr(attr->a_value)) { @@ -5095,6 +5110,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (switch_rtp_ready(v_engine->rtp_session)) { const char *ssrc; + if (v_engine->fir) { + switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_FIR); + } + + if (v_engine->pli) { + switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI); + } + switch_rtp_set_payload_map(v_engine->rtp_session, &v_engine->payload_map); start_video_thread(session); @@ -6436,6 +6459,12 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess } } + + if (v_engine->fir || v_engine->pli) { + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), + "a=rtcp-fb:* %s%s\n", v_engine->fir ? "fir " : "", v_engine->pli ? "pli" : ""); + } + //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", v_engine->ssrc); if (v_engine->ice_out.cands[0][0].ready) { @@ -6465,11 +6494,11 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\n", bw); } - if (vp8) { + if (vp8 && switch_channel_test_flag(session->channel, CF_WEBRTC)) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-fb:%d ccm fir\n", vp8); } - + if (red) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp-fb:%d nack\n", vp8); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index aa296c95da..fab4ddba8a 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1459,7 +1459,7 @@ static void send_fir(switch_rtp_t *rtp_session) } -#if 0 + static void send_pli(switch_rtp_t *rtp_session) { @@ -1542,7 +1542,7 @@ static void send_pli(switch_rtp_t *rtp_session) return; } -#endif + static int check_rtcp_and_ice(switch_rtp_t *rtp_session) { @@ -1557,8 +1557,11 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) } if (rtp_session->fir_countdown == FIR_COUNTDOWN || rtp_session->fir_countdown == 1) { - send_fir(rtp_session); - //send_pli(rtp_session); + if (rtp_session->flags[SWITCH_RTP_FLAG_PLI]) { + send_pli(rtp_session); + } else { + send_fir(rtp_session); + } } rtp_session->fir_countdown--; @@ -3460,9 +3463,9 @@ SWITCH_DECLARE(void) switch_rtp_flush(switch_rtp_t *rtp_session) SWITCH_DECLARE(void) switch_rtp_video_refresh(switch_rtp_t *rtp_session) { - if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->ice.ice_user) { + if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && + (rtp_session->ice.ice_user || rtp_session->flags[SWITCH_RTP_FLAG_FIR] || rtp_session->flags[SWITCH_RTP_FLAG_PLI])) { if (!rtp_session->fir_countdown) { - //send_fir(rtp_session); rtp_session->fir_countdown = FIR_COUNTDOWN; } } From 29c38decab33e6a7c326e4ea432375595674a0b7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 21 Nov 2013 01:41:28 +0500 Subject: [PATCH 119/656] add execute_on_avmd_beep --- src/mod/applications/mod_avmd/mod_avmd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 5d76a28c2e..15f954b326 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -539,6 +539,8 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame) /*! If variance is less than threshold then we have detection */ if(v < VARIANCE_THRESHOLD){ + switch_channel_execute_on(switch_core_session_get_channel(session), "execute_on_avmd_beep"); + /*! Throw an event to FreeSWITCH */ status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP); if(status != SWITCH_STATUS_SUCCESS) { From 3fe701d2415f527f11075242b09c7938aeca02de Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 20 Nov 2013 14:55:34 -0600 Subject: [PATCH 120/656] fix recursive build error --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index a3e942a036..f10899ca8d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,10 +6,10 @@ NAME = freeswitch AM_LIBAPR_CFLAGS := $(shell ./libs/apr/apr-1-config --cflags) AM_LIBAPR_CPPFLAGS := $(shell ./libs/apr/apr-1-config --cppflags --includes) AM_LIBAPR_LDFLAGS := $(shell ./libs/apr/apr-1-config --ldflags) -AM_LIBAPR_LIBS := $(subst $(CURDIR)/,,$(shell ./libs/apr/apr-1-config \--link-libtool \--libs)) +AM_LIBAPR_LIBS := $(subst $(switch_srcdir)/,,$(shell ./libs/apr/apr-1-config \--link-libtool \--libs)) AM_LIBAPU_CPPFLAGS := $(shell ./libs/apr-util/apu-1-config --includes) AM_LIBAPU_LDFLAGS := $(shell ./libs/apr-util/apu-1-config --ldflags) -AM_LIBAPU_LIBS := $(subst $(CURDIR)/,,$(shell ./libs/apr-util/apu-1-config \--link-libtool \--libs)) +AM_LIBAPU_LIBS := $(subst $(switch_srcdir)/,,$(shell ./libs/apr-util/apu-1-config \--link-libtool \--libs)) AM_CFLAGS = $(SWITCH_AM_CFLAGS) $(SWITCH_ANSI_CFLAGS) AM_CPPFLAGS = $(SWITCH_AM_CXXFLAGS) -Ilibs/sofia-sip/libsofia-sip-ua/sdp -Ilibs/sofia-sip/libsofia-sip-ua/su From c07a6b6b9e4a75433dd17b3008d87d2ec41bcd70 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Nov 2013 04:52:11 +0500 Subject: [PATCH 121/656] add polycom support to multicast paging, broadcast all formats at once to support most every popular phone at once --- src/include/switch_apr.h | 1 + src/mod/applications/mod_esf/mod_esf.c | 367 +++++++++++++++++++++---- src/switch_apr.c | 6 + src/switch_rtp.c | 35 +++ 4 files changed, 360 insertions(+), 49 deletions(-) diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index 923d60d985..3cb478a7cf 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -1304,6 +1304,7 @@ SWITCH_DECLARE(switch_status_t) switch_mcast_join(switch_socket_t *sock, switch_ SWITCH_DECLARE(switch_status_t) switch_mcast_hops(switch_socket_t *sock, uint8_t ttl); SWITCH_DECLARE(switch_status_t) switch_mcast_loopback(switch_socket_t *sock, uint8_t opt); +SWITCH_DECLARE(switch_status_t) switch_mcast_interface(switch_socket_t *sock, switch_sockaddr_t *iface); /** @} */ diff --git a/src/mod/applications/mod_esf/mod_esf.c b/src/mod/applications/mod_esf/mod_esf.c index f6a9191877..d8abbb5bcd 100644 --- a/src/mod/applications/mod_esf/mod_esf.c +++ b/src/mod/applications/mod_esf/mod_esf.c @@ -35,6 +35,45 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load); SWITCH_MODULE_DEFINITION(mod_esf, mod_esf_load, NULL, NULL); + + +#ifdef _MSC_VER +#pragma pack(push, r1, 1) +#else +#pragma pack(1) +#endif + + +struct polycom_packet { + switch_byte_t op; + switch_byte_t channel; + uint32_t serno; + uint8_t cid_len; + unsigned char cid[13]; +}; + +typedef struct polycom_packet polycom_packet_t; + +typedef struct { + switch_byte_t codec; + switch_byte_t flags; + uint32_t seq; +} polycom_audio_header_t; + + +typedef struct polycom_alert_packet { + polycom_packet_t header; + polycom_audio_header_t audio_header; + uint8_t data[]; +} polycom_alert_packet_t; + + +#ifdef _MSC_VER +#pragma pack(pop, r1) +#else +#pragma pack() +#endif + struct ls_control_packet { uint32_t unique_id; uint32_t command; @@ -52,35 +91,82 @@ typedef enum { typedef enum { SEND_TYPE_UNKNOWN = 0, SEND_TYPE_RTP = 1, - SEND_TYPE_RAW = 2, - SEND_TYPE_NOMEDIA = 3 + SEND_TYPE_NOMEDIA = 2 } ls_how_t; +static uint32_t SERNO = 0; + +switch_mutex_t *MUTEX = NULL; + +uint32_t get_serno(void) +{ + uint32_t r = 0; + + switch_mutex_lock(MUTEX); + r = SERNO; + switch_mutex_unlock(MUTEX); + + return r; +} + + +void inc_serno(void) +{ + switch_mutex_lock(MUTEX); + SERNO++; + switch_mutex_unlock(MUTEX); + +} + +void dec_serno(void) +{ + switch_mutex_lock(MUTEX); + SERNO--; + switch_mutex_unlock(MUTEX); + +} + + SWITCH_STANDARD_APP(bcast_function) { switch_channel_t *channel = switch_core_session_get_channel(session); - switch_socket_t *socket; - switch_sockaddr_t *audio_addr = NULL, *control_packet_addr; + switch_socket_t *socket, *polycom_socket = NULL; + switch_sockaddr_t *audio_addr = NULL, *control_packet_addr = NULL, *polycom_addr = NULL, *local_addr = NULL; switch_frame_t *read_frame = NULL; switch_status_t status; switch_size_t bytes; ls_control_packet_t control_packet; + unsigned char polycom_buf[1024] = { 0 }; + unsigned char last_polycom_buf[1024] = { 0 }; + uint32_t last_polycom_len = 0; + polycom_packet_t *polycom_packet = (polycom_packet_t *) polycom_buf; + polycom_alert_packet_t *alert_packet = (polycom_alert_packet_t *) polycom_buf; switch_codec_t codec = { 0 }; + switch_codec_t write_codec = { 0 }; switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0}; const char *err; switch_rtp_t *rtp_session = NULL; - switch_port_t rtp_port; - char guess_ip[25]; + switch_port_t rtp_port = 0; ls_how_t ready = SEND_TYPE_UNKNOWN; - //int argc; char *mydata, *argv[5]; char *mcast_ip = "224.168.168.168"; switch_port_t mcast_port = 34567; switch_port_t mcast_control_port = 6061; char *mcast_port_str = "34567"; - const char *esf_broadcast_ip = NULL, *var; + char *polycom_ip = "224.0.1.116"; + const char *source_ip = NULL; + switch_port_t polycom_port = 5001; + const char *var; switch_codec_implementation_t read_impl = { 0 }; int mcast_ttl = 1; + const char *caller_id_name = NULL; + int x = 0; + uint32_t seq = 0; + const char *codec_name = "PCMU"; + int read_rate = 8000; + int need_transcode = 0; + + inc_serno(); switch_core_session_get_read_impl(session, &read_impl); @@ -115,6 +201,9 @@ SWITCH_STANDARD_APP(bcast_function) } } + switch_channel_set_variable_printf(channel, "multicast_ttl", "%d", mcast_ttl); + + if (switch_true(switch_channel_get_variable(channel, SWITCH_BYPASS_MEDIA_VARIABLE))) { switch_core_session_message_t msg = { 0 }; @@ -132,13 +221,27 @@ SWITCH_STANDARD_APP(bcast_function) switch_channel_answer(channel); } + if (!(source_ip = switch_channel_get_variable(channel, "esf_multicast_bind_ip"))) { + if (!(source_ip = switch_channel_get_variable(channel, "local_ip_v4"))) { + source_ip = "127.0.0.1"; + } + } + + /* everyone */ + + if (switch_sockaddr_info_get(&local_addr, source_ip, SWITCH_UNSPEC, + 0, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "address Error\n"); + goto fail; + } + if (switch_socket_create(&socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 1\n"); goto fail; } - if (switch_mcast_hops(socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n"); + if (switch_socket_opt_set(socket, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Option Error\n"); goto fail; } @@ -148,29 +251,121 @@ SWITCH_STANDARD_APP(bcast_function) goto fail; } + if (switch_socket_bind(socket, local_addr) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket bind Error\n"); + goto fail; + } + if (switch_mcast_interface(socket, local_addr) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket interface Error\n"); + goto fail; + } + + if (switch_mcast_join(socket, control_packet_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Multicast Error\n"); + goto fail; + } + + + if (switch_mcast_hops(socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n"); + goto fail; + } + + /* polycom */ + + + if (switch_sockaddr_info_get(&polycom_addr, polycom_ip, SWITCH_UNSPEC, + polycom_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 3\n"); + goto fail; + } + + if (switch_socket_create(&polycom_socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 1\n"); + goto fail; + } + + if (switch_socket_opt_set(polycom_socket, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Option Error\n"); + goto fail; + } + + if (switch_socket_bind(polycom_socket, local_addr) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket bind Error\n"); + goto fail; + } + + + if (switch_mcast_interface(polycom_socket, local_addr) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket interface Error\n"); + goto fail; + } + + if (switch_mcast_join(polycom_socket, polycom_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Multicast Error\n"); + goto fail; + } + + + if (switch_mcast_hops(polycom_socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n"); + goto fail; + } + + while (!ready) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); - if (read_frame && switch_test_flag(read_frame, SFF_CNG)) { - continue; - } if (!SWITCH_READ_ACCEPTABLE(status) || !read_frame) { goto fail; } - if (read_frame->packet && read_frame->packetlen && read_impl.ianacode == 0) { - ready = SEND_TYPE_RAW; - } else { - ready = SEND_TYPE_RTP; + + if (switch_test_flag(read_frame, SFF_CNG)) { + continue; + } + + + ready = SEND_TYPE_RTP; + } + + + alert_packet->audio_header.codec = 0x00; + alert_packet->audio_header.flags = 0; + + if ((var = switch_channel_get_variable(channel, "esf_multicast_write_codec"))) { + if (!strcasecmp(var, "PCMU")) { + codec_name = var; + } else if (!strcasecmp(var, "G722")) { + codec_name = var; + read_rate = 16000; + alert_packet->audio_header.codec = 0x09; } } + if (ready == SEND_TYPE_RTP) { - if (read_impl.ianacode != 0) { + if (strcasecmp(read_impl.iananame, codec_name)) { + need_transcode = 1; + if (switch_core_codec_init(&codec, "L16", NULL, + read_rate, + 20, + 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, + NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { + switch_core_session_set_read_codec(session, &codec); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activation Success\n"); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Activation Fail\n"); + goto fail; + } + + if (switch_core_codec_init(&write_codec, + codec_name, + NULL, 8000, 20, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, @@ -182,39 +377,28 @@ SWITCH_STANDARD_APP(bcast_function) goto fail; } } + - if ((var = switch_channel_get_variable(channel, "esf_broadcast_ip"))) { - esf_broadcast_ip = switch_core_session_strdup(session, var); - } else { - switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET); - esf_broadcast_ip = guess_ip; - } - - - if (!(rtp_port = switch_rtp_request_port(esf_broadcast_ip))) { + if (!(rtp_port = switch_rtp_request_port(source_ip))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Port Error\n"); goto fail; } - rtp_session = switch_rtp_new(esf_broadcast_ip, + rtp_session = switch_rtp_new(source_ip, rtp_port, mcast_ip, mcast_port, - 0, + alert_packet->audio_header.codec, 160, 20000, flags, "soft", &err, switch_core_session_get_pool(session)); - + if (!switch_rtp_ready(rtp_session)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n"); goto fail; } + } else if (ready == SEND_TYPE_NOMEDIA) { switch_yield(10000); - } else if (ready == SEND_TYPE_RAW) { - if (switch_sockaddr_info_get(&audio_addr, mcast_ip, SWITCH_UNSPEC, mcast_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 2\n"); - goto fail; - } } control_packet.unique_id = htonl((u_long) switch_epoch_time_now(NULL)); @@ -227,6 +411,38 @@ SWITCH_STANDARD_APP(bcast_function) bytes = 16; switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes); + + if (!(caller_id_name = switch_channel_get_variable(channel, "caller_id_name"))) { + caller_id_name = "FreeSWITCH"; + } + + strncpy((char *)polycom_packet->cid, caller_id_name, sizeof(polycom_packet->cid)); + polycom_packet->cid_len = 13; + + polycom_packet->op = 0x0F; + polycom_packet->channel = 0x1a; + polycom_packet->serno = htonl(get_serno()); + + if ((var = switch_channel_get_variable(channel, "esf_multicast_channel"))) { + int channel_no = atoi(var); + + if (channel_no > 0 && channel_no < 255) { + polycom_packet->channel = (uint8_t) channel_no; + } + } + + for (x = 0; x < 32; x++) { + bytes = sizeof(polycom_packet_t); + switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_packet, &bytes); + //switch_yield(30000); + } + + polycom_packet->op = 0x10; + + if ((var = switch_channel_get_variable(channel, "esf_multicast_alert_sound"))) { + switch_ivr_displace_session(session, var, 0, "mr"); + } + while (switch_channel_ready(channel)) { status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); @@ -234,26 +450,57 @@ SWITCH_STANDARD_APP(bcast_function) if (!SWITCH_READ_ACCEPTABLE(status)) { break; } + if (switch_test_flag(read_frame, SFF_CNG)) { continue; } - if (ready == SEND_TYPE_RTP) { - short *dbuf; - unsigned char *ebuf; - uint32_t i; - unsigned char encoded_data[4192]; - dbuf = read_frame->data; - ebuf = encoded_data; - - for (i = 0; i < read_frame->datalen / sizeof(short); i++) { - ebuf[i] = linear_to_ulaw(dbuf[i]); + if (ready == SEND_TYPE_RTP) { + unsigned char *ebuf; + unsigned char encoded_data[4192]; + uint32_t encoded_datalen = sizeof(encoded_data); + + if (need_transcode) { + uint32_t rate = codec.implementation->actual_samples_per_second; + uint32_t flag = 0; + + ebuf = encoded_data; + + switch_core_codec_encode(&write_codec, + &codec, + read_frame->data, + read_frame->datalen, + read_impl.actual_samples_per_second, + ebuf, &encoded_datalen, &rate, &flag); + + read_frame->data = encoded_data; + read_frame->datalen = encoded_datalen; + + } else { + ebuf = read_frame->data; + encoded_datalen = read_frame->datalen; } - read_frame->data = encoded_data; - read_frame->datalen = read_frame->datalen / 2; + switch_rtp_write_frame(rtp_session, read_frame); - read_frame->data = dbuf; - read_frame->datalen = read_frame->datalen * 2; + + seq += 160; + + alert_packet->audio_header.seq = htonl(seq); + + if (last_polycom_len) { + memcpy(alert_packet->data, last_polycom_buf, last_polycom_len); + memcpy(alert_packet->data + last_polycom_len, ebuf, encoded_datalen); + } else { + memcpy(alert_packet->data, ebuf, encoded_datalen); + } + + bytes = sizeof(*alert_packet) + encoded_datalen + last_polycom_len; + + switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_buf, &bytes); + + last_polycom_len = encoded_datalen; + memcpy((void *)last_polycom_buf, (void *)ebuf, last_polycom_len); + } else { bytes = read_frame->packetlen; switch_socket_sendto(socket, audio_addr, 0, read_frame->packet, &bytes); @@ -267,6 +514,16 @@ SWITCH_STANDARD_APP(bcast_function) bytes = 8; switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes); + + polycom_packet->op = 0xFF; + //switch_yield(50000); + + for (x = 0; x < 12; x++) { + bytes = sizeof(*polycom_packet); + switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_packet, &bytes); + //switch_yield(30000); + } + fail: switch_core_session_set_read_codec(session, NULL); @@ -281,6 +538,16 @@ SWITCH_STANDARD_APP(bcast_function) if (socket) { switch_socket_close(socket); } + + if (polycom_socket) { + switch_socket_close(polycom_socket); + } + + if (rtp_port) { + switch_rtp_release_port(source_ip, rtp_port); + } + + dec_serno(); return; } @@ -289,6 +556,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load) { switch_application_interface_t *app_interface; + switch_mutex_init(&MUTEX, SWITCH_MUTEX_NESTED, pool); + /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_APP(app_interface, "esf_page_group", NULL, NULL, bcast_function, NULL, SAF_NONE); diff --git a/src/switch_apr.c b/src/switch_apr.c index d7717290bd..9773e31b26 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -834,6 +834,12 @@ SWITCH_DECLARE(switch_status_t) switch_mcast_loopback(switch_socket_t *sock, uin return apr_mcast_loopback(sock, opt); } +SWITCH_DECLARE(switch_status_t) switch_mcast_interface(switch_socket_t *sock, switch_sockaddr_t *iface) +{ + return apr_mcast_interface(sock, iface); +} + + /* socket functions */ SWITCH_DECLARE(const char *) switch_get_addr(char *buf, switch_size_t len, switch_sockaddr_t *in) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index fab4ddba8a..85a471ac16 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1999,6 +1999,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s { switch_socket_t *new_sock = NULL, *old_sock = NULL; switch_status_t status = SWITCH_STATUS_FALSE; + int j = 0; #ifndef WIN32 char o[5] = "TEST", i[5] = ""; switch_size_t len, ilen = 0; @@ -2057,6 +2058,40 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s goto done; } + + if ((j = atoi(host)) && j > 223 && j < 240) { /* mcast */ + if (switch_mcast_interface(new_sock, rtp_session->local_addr) != SWITCH_STATUS_SUCCESS) { + *err = "Multicast Socket interface Error"; + goto done; + } + + if (switch_mcast_join(new_sock, rtp_session->local_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) { + *err = "Multicast Error"; + goto done; + } + + if (rtp_session->session) { + switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session); + const char *var; + + if ((var = switch_channel_get_variable(channel, "multicast_ttl"))) { + int ttl = atoi(var); + + if (ttl > 0 && ttl < 256) { + if (switch_mcast_hops(new_sock, (uint8_t) ttl) != SWITCH_STATUS_SUCCESS) { + *err = "Mutlicast TTL set failed"; + goto done; + } + + } + } + + } + + } + + + #ifndef WIN32 len = sizeof(i); switch_socket_opt_set(new_sock, SWITCH_SO_NONBLOCK, TRUE); From ca8f121977b1eeb6f1707f9b50b1d2455cb3b55b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Nov 2013 04:53:34 +0500 Subject: [PATCH 122/656] fix regression from recent refactor that causes infinite loop on unexpected disconnect --- libs/esl/src/esl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c index 67b82fbe6d..e8ed39aa68 100644 --- a/libs/esl/src/esl.c +++ b/libs/esl/src/esl.c @@ -1231,8 +1231,9 @@ static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t data if ((activity & ESL_POLL_ERROR)) { activity = -1; } else if ((activity & ESL_POLL_READ)) { - activity = recv(handle->sock, data, datalen, 0); - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { + if (!(activity = recv(handle->sock, data, datalen, 0))) { + activity = -1; + } else if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { activity = 0; } } From b8dc07132ab5ebda769dd85353e04947a1c2f561 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Nov 2013 08:55:45 +0500 Subject: [PATCH 123/656] FS-5959 i hate this ticket --- src/switch_core_media.c | 33 ++++++++++++++++++++------------- src/switch_rtp.c | 3 ++- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index fdb4043f54..c25c2e5ed1 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -535,6 +535,7 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se int exists = 0; switch_media_handle_t *smh; switch_rtp_engine_t *engine; + int local_pt = 0; switch_assert(session); @@ -549,12 +550,13 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se for (pmap = engine->payload_map; pmap && pmap->allocated; pmap = pmap->next) { exists = (!strcasecmp(name, pmap->iananame) && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime)); - + if (exists) { if (!zstr(fmtp) && !zstr(pmap->rm_fmtp)) { if (strcmp(pmap->rm_fmtp, fmtp)) { exists = 0; + local_pt = pmap->pt; continue; } } @@ -589,15 +591,18 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se pmap->rate = rate; } - if (!zstr(fmtp) && (!pmap->rm_fmtp || strcmp(pmap->rm_fmtp, fmtp))) { + if (!zstr(fmtp) && (zstr(pmap->rm_fmtp) || strcmp(pmap->rm_fmtp, fmtp))) { pmap->rm_fmtp = switch_core_strdup(session->pool, fmtp); } pmap->allocated = 1; - pmap->recv_pt = (switch_payload_t)pt; + + + pmap->recv_pt = (switch_payload_t) pt; + if (sdp_type == SDP_TYPE_REQUEST || !exists) { - pmap->pt = (switch_payload_t)pt; + pmap->pt = (switch_payload_t) (local_pt ? local_pt : pt); } if (negotiated) { @@ -3290,7 +3295,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s pmap->rm_encoding = switch_core_session_strdup(session, (char *) mmap->rm_encoding); pmap->iananame = switch_core_session_strdup(session, (char *) mimp->iananame); - pmap->pt = (switch_payload_t) mmap->rm_pt; + pmap->recv_pt = (switch_payload_t) mmap->rm_pt; pmap->rm_rate = mimp->samples_per_second; pmap->adv_rm_rate = mimp->samples_per_second; if (strcasecmp(mimp->iananame, "g722")) { @@ -3330,7 +3335,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (match) { char tmp[50]; - const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload"); + //const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload"); switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port); @@ -3338,11 +3343,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp); +#if 0 if (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND && (!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) { switch_core_media_get_offered_pt(session, matches[0].imp, &a_engine->cur_payload_map->recv_pt); } +#endif switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt); switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp); @@ -3521,7 +3528,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (m_idx) { char tmp[50]; - const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_video_codec_payload"); + //const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_video_codec_payload"); int j = 0; if (greedy) { /* sort in favor of mine */ @@ -3541,7 +3548,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s matches[j].imp->samples_per_second, matches[j].imp->microseconds_per_packet / 1000, SWITCH_TRUE); - if (j == 0) { v_engine->cur_payload_map = pmap; } @@ -3550,7 +3556,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s map = matches[j].map; pmap->rm_encoding = switch_core_session_strdup(session, (char *) map->rm_encoding); - pmap->pt = (switch_payload_t) map->rm_pt; + pmap->recv_pt = (switch_payload_t) map->rm_pt; pmap->rm_rate = map->rm_rate; pmap->codec_ms = mimp->microseconds_per_packet / 1000; @@ -3562,11 +3568,12 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s pmap->agreed_pt = (switch_payload_t) map->rm_pt; - pmap->recv_pt = (switch_payload_t)map->rm_pt; +#if 0 if (j == 0 && (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { switch_core_media_get_offered_pt(session, mimp, &pmap->recv_pt); } +#endif } @@ -5117,7 +5124,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (v_engine->pli) { switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_PLI); } - + switch_rtp_set_payload_map(v_engine->rtp_session, &v_engine->payload_map); start_video_thread(session); @@ -7900,7 +7907,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess map->rm_pt, map->rm_rate, ptime, - SWITCH_FALSE); + SWITCH_TRUE); } } } @@ -8287,7 +8294,7 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s } if ((tmp = switch_channel_get_variable(session->channel, "rtp_video_recv_pt"))) { - v_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp);; + v_engine->cur_payload_map->recv_pt = (switch_payload_t)atoi(tmp); } v_engine->cur_payload_map->rm_encoding = (char *) switch_channel_get_variable(session->channel, "rtp_use_video_codec_name"); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 85a471ac16..490137e08b 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4121,6 +4121,7 @@ static int check_recv_payload(switch_rtp_t *rtp_session) if (!pmap->negotiated) { continue; } + if (rtp_session->recv_msg.header.pt == pmap->pt) { ok = 1; } @@ -6242,7 +6243,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra switch_mutex_lock(rtp_session->flag_mutex); for (pmap = *rtp_session->pmaps; pmap; pmap = pmap->next) { - if (pmap->hash == frame->pmap->hash && !strcmp(pmap->iananame, frame->pmap->iananame)) { + if (pmap->negotiated && pmap->hash == frame->pmap->hash) { payload = pmap->recv_pt; break; } From 9c72dc950e3b08c4b987e62a1a02358a319d599b Mon Sep 17 00:00:00 2001 From: Seven Du Date: Fri, 22 Nov 2013 14:23:18 +0800 Subject: [PATCH 124/656] add CF_MEDIA_PAUSE channel flag to allow waiting for IO before media codec is ready This could be used at endpoints where signalling and media negotiated separately like in H323 --- src/include/switch_types.h | 1 + src/switch_core_io.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 0567fd2455..cf6f4c247d 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1362,6 +1362,7 @@ typedef enum { CF_VIDEO_ECHO, CF_SLA_INTERCEPT, CF_VIDEO_BREAK, + CF_MEDIA_PAUSE, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */ CF_FLAG_MAX diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 13c15874f4..d571da41b0 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -26,6 +26,7 @@ * Anthony Minessale II * Michael Jerris * Paul D. Tinsley + * Seven Du * * * switch_core_io.c -- Main Core Library (Media I/O) @@ -45,6 +46,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor return SWITCH_STATUS_FALSE; } + if (switch_channel_test_flag(session->channel, CF_MEDIA_PAUSE)) { + return SWITCH_STATUS_SUCCESS; + } + if (session->endpoint_interface->io_routines->write_video_frame) { if ((status = session->endpoint_interface->io_routines->write_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { for (ptr = session->event_hooks.video_write_frame; ptr; ptr = ptr->next) { @@ -69,6 +74,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core return SWITCH_STATUS_FALSE; } + if (switch_channel_test_flag(session->channel, CF_MEDIA_PAUSE)) { + *frame = &runtime.dummy_cng_frame; + switch_yield(20000); + return SWITCH_STATUS_SUCCESS; + } + if (session->endpoint_interface->io_routines->read_video_frame) { if ((status = session->endpoint_interface->io_routines->read_video_frame(session, frame, flags, stream_id)) == SWITCH_STATUS_SUCCESS) { for (ptr = session->event_hooks.video_read_frame; ptr; ptr = ptr->next) { @@ -165,6 +176,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi *frame = &runtime.dummy_cng_frame; return SWITCH_STATUS_SUCCESS; } + + if (switch_channel_test_flag(session->channel, CF_MEDIA_PAUSE)) { + switch_yield(20000); + *frame = &runtime.dummy_cng_frame; + // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Media Paused!!!!\n"); + return SWITCH_STATUS_SUCCESS; + } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); return SWITCH_STATUS_FALSE; @@ -1033,6 +1052,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess } } + if (switch_channel_test_flag(session->channel, CF_MEDIA_PAUSE)) { + return SWITCH_STATUS_SUCCESS; + } + if (!(session->write_codec && switch_core_codec_ready(session->write_codec)) && !pass_cng) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no write codec.\n", switch_channel_get_name(session->channel)); switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); From 3a0f93478827e76012ff1a853254db71460bc16d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Nov 2013 18:52:21 +0500 Subject: [PATCH 125/656] revert one change --- src/switch_core_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index c25c2e5ed1..25af9b4e29 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -7907,7 +7907,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess map->rm_pt, map->rm_rate, ptime, - SWITCH_TRUE); + SWITCH_FALSE); } } } From 4129adc9ac94003d5c24cfedb993c5831a9ec9a7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Nov 2013 22:21:32 +0500 Subject: [PATCH 126/656] update more fields on re-subscribe --- src/mod/endpoints/mod_sofia/sofia_presence.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index ef28993d89..6f72d1d51b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3772,9 +3772,12 @@ void sofia_presence_handle_sip_i_subscribe(int status, sstr = switch_mprintf("active;expires=%ld", exp_delta); sql = switch_mprintf("update sip_subscriptions " - "set expires=%ld " + "set expires=%ld, " + "network_ip='%q',network_port='%q',sip_user='%q',sip_host='%q',full_via='%q',full_to='%q',full_from='%q',contact='%q' " "where call_id='%q' and profile_name='%q' and hostname='%q'", (long) switch_epoch_time_now(NULL) + exp_delta, + np.network_ip, np.network_port, from_user, from_host, full_via, full_to, full_from, contact_str, + call_id, profile->name, mod_sofia_globals.hostname); if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) { From 726b607667c0c1aea6280f04ded4d183a65bb95b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Nov 2013 22:52:59 +0500 Subject: [PATCH 127/656] FS-5841 --resolve --- .../mod_voicemail/mod_voicemail.c | 8 +-- src/switch_xml.c | 68 ++++++++++++------- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 6f2e5d68c9..3d41f90c51 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -1724,7 +1724,7 @@ static switch_status_t listen_file(switch_core_session_t *session, vm_profile_t switch_event_create(&my_params, SWITCH_EVENT_REQUEST_PARAMS); switch_assert(my_params); - status = switch_xml_locate_user_merged("id", vm_cc, cbt->domain, NULL, &x_user, my_params); + status = switch_xml_locate_user_merged("id:number-alias", vm_cc, cbt->domain, NULL, &x_user, my_params); switch_event_destroy(&my_params); if (status != SWITCH_STATUS_SUCCESS) { @@ -2440,7 +2440,7 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "destination_number", caller_profile->destination_number); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "caller_id_number", caller_id_number); - if (switch_xml_locate_user_merged("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"), + if (switch_xml_locate_user_merged("id:number-alias", myid, domain_name, switch_channel_get_variable(channel, "network_addr"), &x_user, params) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", myid, domain_name); ok = 0; @@ -3388,7 +3388,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p switch_assert(locate_params); switch_event_add_header_string(locate_params, SWITCH_STACK_BOTTOM, "action", "voicemail-lookup"); - if (switch_xml_locate_user_merged("id", id, domain_name, switch_channel_get_variable(channel, "network_addr"), + if (switch_xml_locate_user_merged("id:number-alias", id, domain_name, switch_channel_get_variable(channel, "network_addr"), &x_user, locate_params) == SWITCH_STATUS_SUCCESS) { id = switch_core_session_strdup(session, switch_xml_attr(x_user, "id")); @@ -5689,7 +5689,7 @@ SWITCH_STANDARD_API(vm_fsdb_auth_login_function) } switch_event_create(¶ms, SWITCH_EVENT_GENERAL); - if (switch_xml_locate_user_merged("id", id, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { + if (switch_xml_locate_user_merged("id:number-alias", id, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Can't find user [%s@%s]\n", id, domain); stream->write_function(stream, "-ERR User not found\n"); } else { diff --git a/src/switch_xml.c b/src/switch_xml.c index 81ec0609b8..d1a9a1ca61 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2044,34 +2044,52 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_merged(const char *key, c { switch_xml_t xml, domain, group, x_user, x_user_dup; switch_status_t status = SWITCH_STATUS_FALSE; + char *kdup = NULL; + char *keys[10] = {0}; + int i, nkeys; - if ((status = switch_xml_locate_user_cache(key, user_name, domain_name, &x_user)) == SWITCH_STATUS_SUCCESS) { - *user = x_user; - } else if ((status = switch_xml_locate_user(key, user_name, domain_name, ip, &xml, &domain, &x_user, &group, params)) == SWITCH_STATUS_SUCCESS) { - const char *cacheable = NULL; - - x_user_dup = switch_xml_dup(x_user); - switch_xml_merge_user(x_user_dup, domain, group); - - cacheable = switch_xml_attr(x_user_dup, "cacheable"); - if (switch_true(cacheable)) { - switch_time_t expires = 0; - switch_time_t time_now = 0; - - if (switch_is_number(cacheable)) { - int cache_ms = atol(cacheable); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "caching lookup for user %s@%s for %d milliseconds\n", user_name, domain_name, cache_ms); - time_now = switch_micro_time_now(); - expires = time_now + (cache_ms * 1000); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "caching lookup for user %s@%s indefinitely\n", user_name, domain_name); - } - switch_xml_user_cache(key, user_name, domain_name, x_user_dup, expires); - } - *user = x_user_dup; - switch_xml_free(xml); + if (strchr(key, ':')) { + kdup = strdup(key); + nkeys = switch_split(kdup, ':', keys); + } else { + keys[0] = (char *)key; + nkeys = 1; } + for(i = 0; i < nkeys; i++) { + if ((status = switch_xml_locate_user_cache(keys[i], user_name, domain_name, &x_user)) == SWITCH_STATUS_SUCCESS) { + *user = x_user; + break; + } else if ((status = switch_xml_locate_user(keys[i], user_name, domain_name, ip, &xml, &domain, &x_user, &group, params)) == SWITCH_STATUS_SUCCESS) { + const char *cacheable = NULL; + + x_user_dup = switch_xml_dup(x_user); + switch_xml_merge_user(x_user_dup, domain, group); + + cacheable = switch_xml_attr(x_user_dup, "cacheable"); + if (switch_true(cacheable)) { + switch_time_t expires = 0; + switch_time_t time_now = 0; + + if (switch_is_number(cacheable)) { + int cache_ms = atol(cacheable); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "caching lookup for user %s@%s for %d milliseconds\n", + user_name, domain_name, cache_ms); + time_now = switch_micro_time_now(); + expires = time_now + (cache_ms * 1000); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "caching lookup for user %s@%s indefinitely\n", user_name, domain_name); + } + switch_xml_user_cache(keys[i], user_name, domain_name, x_user_dup, expires); + } + *user = x_user_dup; + switch_xml_free(xml); + break; + } + } + + switch_safe_free(kdup); + return status; } From 94939d1bff7b6f9e3b2a7bfcd238fdd9cb5f6bf1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 23 Nov 2013 01:12:24 +0500 Subject: [PATCH 128/656] add nomux flag when playing to a member to block other audio --- .../mod_conference/mod_conference.c | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 1564b1898d..cc3003b0cc 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -273,6 +273,7 @@ typedef struct conference_file_node { uint32_t leadin; struct conference_file_node *next; char *file; + switch_bool_t mux; } conference_file_node_t; typedef enum { @@ -540,7 +541,7 @@ static void launch_conference_video_thread(conference_obj_t *conference); static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *obj); static switch_status_t conference_local_play_file(conference_obj_t *conference, switch_core_session_t *session, char *path, uint32_t leadin, void *buf, uint32_t buflen); -static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin); +static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin, switch_bool_t mux); static switch_status_t conference_member_say(conference_member_t *member, char *text, uint32_t leadin); static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop); static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_core_session_t *session, switch_memory_pool_t *pool); @@ -3160,7 +3161,7 @@ static void conference_loop_fn_energy_up(conference_member_t *member, caller_con switch_snprintf(str, sizeof(str), "%d", abs(member->energy_level) / 200); for (p = str; p && *p; p++) { switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } @@ -3192,7 +3193,7 @@ static void conference_loop_fn_energy_equ_conf(conference_member_t *member, call switch_snprintf(str, sizeof(str), "%d", abs(member->energy_level) / 200); for (p = str; p && *p; p++) { switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } } @@ -3224,7 +3225,7 @@ static void conference_loop_fn_energy_dn(conference_member_t *member, caller_con switch_snprintf(str, sizeof(str), "%d", abs(member->energy_level) / 200); for (p = str; p && *p; p++) { switch_snprintf(msg, sizeof(msg), "digits/%c.wav", *p); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } } @@ -3253,11 +3254,11 @@ static void conference_loop_fn_volume_talk_up(conference_member_t *member, calle if (member->volume_out_level < 0) { switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_out_level); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_out_level)); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } @@ -3285,11 +3286,11 @@ static void conference_loop_fn_volume_talk_zero(conference_member_t *member, cal if (member->volume_out_level < 0) { switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_out_level); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_out_level)); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } static void conference_loop_fn_volume_talk_dn(conference_member_t *member, caller_control_action_t *action) @@ -3316,11 +3317,11 @@ static void conference_loop_fn_volume_talk_dn(conference_member_t *member, calle if (member->volume_out_level < 0) { switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_out_level); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_out_level)); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } static void conference_loop_fn_volume_listen_up(conference_member_t *member, caller_control_action_t *action) @@ -3347,11 +3348,11 @@ static void conference_loop_fn_volume_listen_up(conference_member_t *member, cal if (member->volume_in_level < 0) { switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_in_level); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level)); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } @@ -3378,11 +3379,11 @@ static void conference_loop_fn_volume_listen_zero(conference_member_t *member, c if (member->volume_in_level < 0) { switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_in_level); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level)); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } @@ -3410,11 +3411,11 @@ static void conference_loop_fn_volume_listen_dn(conference_member_t *member, cal if (member->volume_in_level < 0) { switch_snprintf(msg, sizeof(msg), "currency/negative.wav", member->volume_in_level); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } switch_snprintf(msg, sizeof(msg), "digits/%d.wav", abs(member->volume_in_level)); - conference_member_play_file(member, msg, 0); + conference_member_play_file(member, msg, 0, SWITCH_TRUE); } static void conference_loop_fn_event(conference_member_t *member, caller_control_action_t *action) @@ -4000,9 +4001,13 @@ static void member_add_file_data(conference_member_t *member, int16_t *data, swi } for (i = 0; i < file_sample_len; i++) { - sample = data[i] + file_frame[i]; - switch_normalize_to_16bit(sample); - data[i] = sample; + if (member->fnode->mux) { + sample = data[i] + file_frame[i]; + switch_normalize_to_16bit(sample); + data[i] = sample; + } else { + data[i] = file_frame[i]; + } } } @@ -4162,7 +4167,7 @@ static void conference_loop_output(conference_member_t *member) goto end; } - conference_member_play_file(member, "tone_stream://%(500,0,640)", 0); + conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE); } if (!switch_test_flag(member->conference, CFLAG_ANSWERED)) { @@ -4324,7 +4329,7 @@ static void conference_loop_output(conference_member_t *member) if (switch_test_flag(member, MFLAG_INDICATE_MUTE)) { if (!zstr(member->conference->muted_sound)) { - conference_member_play_file(member, member->conference->muted_sound, 0); + conference_member_play_file(member, member->conference->muted_sound, 0, SWITCH_TRUE); } else { char msg[512]; @@ -4336,7 +4341,7 @@ static void conference_loop_output(conference_member_t *member) if (switch_test_flag(member, MFLAG_INDICATE_MUTE_DETECT)) { if (!zstr(member->conference->mute_detect_sound)) { - conference_member_play_file(member, member->conference->mute_detect_sound, 0); + conference_member_play_file(member, member->conference->mute_detect_sound, 0, SWITCH_TRUE); } else { char msg[512]; @@ -4348,7 +4353,7 @@ static void conference_loop_output(conference_member_t *member) if (switch_test_flag(member, MFLAG_INDICATE_UNMUTE)) { if (!zstr(member->conference->unmuted_sound)) { - conference_member_play_file(member, member->conference->unmuted_sound, 0); + conference_member_play_file(member, member->conference->unmuted_sound, 0, SWITCH_TRUE); } else { char msg[512]; @@ -4850,7 +4855,7 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char * } /* Play a file in the conference room to a member */ -static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin) +static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin, switch_bool_t mux) { switch_status_t status = SWITCH_STATUS_FALSE; char *dfile = NULL, *expanded = NULL; @@ -4897,6 +4902,8 @@ static switch_status_t conference_member_play_file(conference_member_t *member, } fnode->type = NODE_TYPE_FILE; fnode->leadin = leadin; + fnode->mux = mux; + /* Open the file */ fnode->fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; if (switch_core_file_open(&fnode->fh, @@ -6234,12 +6241,17 @@ static switch_status_t conf_api_sub_play(conference_obj_t *conference, switch_st stream->write_function(stream, "(play) File: %s not found.\n", argv[2] ? argv[2] : "(unspecified)"); } ret_status = SWITCH_STATUS_SUCCESS; - } else if (argc == 4) { + } else if (argc >= 4) { uint32_t id = atoi(argv[3]); conference_member_t *member; + switch_bool_t mux = SWITCH_TRUE; + + if (argc > 4 && !strcasecmp(argv[4], "nomux")) { + mux = SWITCH_FALSE; + } if ((member = conference_member_get(conference, id))) { - if (conference_member_play_file(member, argv[2], 0) == SWITCH_STATUS_SUCCESS) { + if (conference_member_play_file(member, argv[2], 0, mux) == SWITCH_STATUS_SUCCESS) { stream->write_function(stream, "(play) Playing file %s to member %u\n", argv[2], id); if (test_eflag(conference, EFLAG_PLAY_FILE_MEMBER) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { @@ -7040,7 +7052,7 @@ static api_command_t conf_api_sub_commands[] = { {"energy", (void_fn_t) & conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET, "energy", " []"}, {"volume_in", (void_fn_t) & conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET, "volume_in", " []"}, {"volume_out", (void_fn_t) & conf_api_sub_volume_out, CONF_API_SUB_MEMBER_TARGET, "volume_out", " []"}, - {"play", (void_fn_t) & conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "play", " [async|]"}, + {"play", (void_fn_t) & conf_api_sub_play, CONF_API_SUB_ARGS_SPLIT, "play", " [async| [nomux]]"}, {"pause_play", (void_fn_t) & conf_api_sub_pause_play, CONF_API_SUB_ARGS_SPLIT, "pause", ""}, {"file_seek", (void_fn_t) & conf_api_sub_file_seek, CONF_API_SUB_ARGS_SPLIT, "file_seek", "[+-]"}, {"say", (void_fn_t) & conf_api_sub_say, CONF_API_SUB_ARGS_AS_ONE, "say", ""}, From c7f00c3e21cf628acd818167caaba8b88e6bfad6 Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Fri, 22 Nov 2013 20:13:49 +0000 Subject: [PATCH 129/656] Add queue talk time and hold time stats to consumer and caller stop events. --- src/mod/applications/mod_fifo/mod_fifo.c | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index e5c12c0998..4ba7b01f78 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -2244,6 +2244,10 @@ static void dec_use_count(switch_core_session_t *session, const char *type) if (type) { if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + uint64_t hold_usec = 0, tt_usec = 0; + switch_caller_profile_t *originator_cp = NULL; + + originator_cp = switch_channel_get_caller_profile(channel); switch_channel_event_set_data(channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", MANUAL_QUEUE_NAME); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "channel-consumer-stop"); @@ -2252,6 +2256,18 @@ static void dec_use_count(switch_core_session_t *session, const char *type) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", outbound_id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", fifo_get_use_count(outbound_id)); } + hold_usec = originator_cp->times->hold_accum; + tt_usec = (switch_micro_time_now() - originator_cp->times->bridged) - hold_usec; + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-us", "%lu", originator_cp->times->bridged); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-ms", "%lu", (uint64_t)(originator_cp->times->bridged / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-s", "%lu", (uint64_t)(originator_cp->times->bridged / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-us", "%lu", tt_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-ms", "%lu", (uint64_t)(tt_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-s", "%lu", (uint64_t)(tt_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-us", "%lu", hold_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-ms", "%lu", (uint64_t)(hold_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-s", "%lu", (uint64_t)(hold_usec / 1000000)); + switch_event_fire(&event); } } @@ -3260,6 +3276,7 @@ SWITCH_STANDARD_APP(fifo_function) if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + uint64_t hold_usec = 0, tt_usec = 0; switch_channel_event_set_data(channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", arg_fifo_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "channel-consumer-stop"); @@ -3268,6 +3285,18 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", outbound_id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", fifo_get_use_count(outbound_id)); } + hold_usec = originator_cp->times->hold_accum; + tt_usec = (switch_micro_time_now() - originator_cp->times->bridged) - hold_usec; + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-us", "%lu", originator_cp->times->bridged); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-ms", "%lu", (uint64_t)(originator_cp->times->bridged / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-s", "%lu", (uint64_t)(originator_cp->times->bridged / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-us", "%lu", tt_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-ms", "%lu", (uint64_t)(tt_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-s", "%lu", (uint64_t)(tt_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-us", "%lu", hold_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-ms", "%lu", (uint64_t)(hold_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-s", "%lu", (uint64_t)(hold_usec / 1000000)); + switch_event_fire(&event); } @@ -3286,9 +3315,18 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_fire(&event); } if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + uint64_t hold_usec = 0, tt_usec = 0; switch_channel_event_set_data(other_channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "bridge-caller-stop"); + hold_usec = originatee_cp->times->hold_accum; + tt_usec = (switch_micro_time_now() - originatee_cp->times->bridged) - hold_usec; + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-us", "%lu", tt_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-ms", "%lu", (uint64_t)(tt_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-s", "%lu", (uint64_t)(tt_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-us", "%lu", hold_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-ms", "%lu", (uint64_t)(hold_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-s", "%lu", (uint64_t)(hold_usec / 1000000)); switch_event_fire(&event); } From 8015a3a0a6b514886310ecd37e0d1833d5833b62 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 23 Nov 2013 02:32:02 +0500 Subject: [PATCH 130/656] fix typo that caused a seg in presesnce --- src/mod/endpoints/mod_sofia/sofia_presence.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 6f72d1d51b..90f251dfb9 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3773,10 +3773,10 @@ void sofia_presence_handle_sip_i_subscribe(int status, sql = switch_mprintf("update sip_subscriptions " "set expires=%ld, " - "network_ip='%q',network_port='%q',sip_user='%q',sip_host='%q',full_via='%q',full_to='%q',full_from='%q',contact='%q' " + "network_ip='%q',network_port='%d',sip_user='%q',sip_host='%q',full_via='%q',full_to='%q;tag=%q',full_from='%q',contact='%q' " "where call_id='%q' and profile_name='%q' and hostname='%q'", (long) switch_epoch_time_now(NULL) + exp_delta, - np.network_ip, np.network_port, from_user, from_host, full_via, full_to, full_from, contact_str, + np.network_ip, np.network_port, from_user, from_host, full_via, full_to, use_to_tag, full_from, contact_str, call_id, profile->name, mod_sofia_globals.hostname); From 882b82aa91c5aedfcdc79616d4c91f70f26d11b5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 23 Nov 2013 02:53:05 +0500 Subject: [PATCH 131/656] pass callee_id on early --- src/switch_ivr_originate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index b30df42a98..a284bfc036 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -3478,6 +3478,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { status = SWITCH_STATUS_SUCCESS; } else { + switch_channel_pass_callee_id(peer_channel, caller_channel); status = switch_channel_pre_answer(caller_channel); } } else { From b64cbe33b4f132ef9621e62e9c5cd6ee51d0d129 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 22 Nov 2013 16:21:41 -0600 Subject: [PATCH 132/656] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 719 +++++++++++++++++- src/mod/languages/mod_managed/managed/swig.cs | 560 +++++++++++++- 2 files changed, 1255 insertions(+), 24 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 2c57e207a4..4d4750877c 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -6967,6 +6967,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_node_t_hup_profile_get(void * } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_node_t_direction_set(void * jarg1, int jarg2) { + switch_device_node_t *arg1 = (switch_device_node_t *) 0 ; + switch_call_direction_t arg2 ; + + arg1 = (switch_device_node_t *)jarg1; + arg2 = (switch_call_direction_t)jarg2; + if (arg1) (arg1)->direction = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_device_node_t_direction_get(void * jarg1) { + int jresult ; + switch_device_node_t *arg1 = (switch_device_node_t *) 0 ; + switch_call_direction_t result; + + arg1 = (switch_device_node_t *)jarg1; + result = (switch_call_direction_t) ((arg1)->direction); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_node_t_parent_set(void * jarg1, void * jarg2) { switch_device_node_t *arg1 = (switch_device_node_t *) 0 ; switch_device_record_s *arg2 = (switch_device_record_s *) 0 ; @@ -7055,6 +7078,52 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_total_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_total_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->total_in = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_total_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->total_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_total_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->total_out = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_total_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->total_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_offhook_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -7078,6 +7147,52 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_offhook_get(vo } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_offhook_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->offhook_in = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_offhook_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->offhook_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_offhook_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->offhook_out = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_offhook_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->offhook_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_active_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -7101,6 +7216,52 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_active_get(voi } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_active_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->active_in = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_active_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->active_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_active_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->active_out = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_active_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->active_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_held_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -7124,6 +7285,52 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_held_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_held_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->held_in = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_held_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->held_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_held_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->held_out = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_held_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->held_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_hup_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -7147,6 +7354,52 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_hup_get(void * } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_hup_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->hup_in = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_hup_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->hup_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_hup_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->hup_out = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_hup_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->hup_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ringing_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -7170,6 +7423,52 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ringing_get(vo } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ringing_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->ringing_in = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ringing_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->ringing_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ringing_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->ringing_out = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ringing_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->ringing_out); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_early_set(void * jarg1, unsigned long jarg2) { switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; uint32_t arg2 ; @@ -7193,6 +7492,75 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_early_get(void } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_early_in_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->early_in = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_early_in_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->early_in); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_early_out_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->early_out = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_early_out_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->early_out); + jresult = (unsigned long)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_stats_t_ring_wait_set(void * jarg1, unsigned long jarg2) { + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t arg2 ; + + arg1 = (switch_device_stats_t *)jarg1; + arg2 = (uint32_t)jarg2; + if (arg1) (arg1)->ring_wait = arg2; + +} + + +SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_device_stats_t_ring_wait_get(void * jarg1) { + unsigned long jresult ; + switch_device_stats_t *arg1 = (switch_device_stats_t *) 0 ; + uint32_t result; + + arg1 = (switch_device_stats_t *)jarg1; + result = (uint32_t) ((arg1)->ring_wait); + jresult = (unsigned long)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_device_stats_t() { void * jresult ; switch_device_stats_t *result = 0 ; @@ -7318,6 +7686,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_stats_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_last_stats_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_device_stats_t *arg2 = (switch_device_stats_t *) 0 ; + + arg1 = (switch_device_record_t *)jarg1; + arg2 = (switch_device_stats_t *)jarg2; + if (arg1) (arg1)->last_stats = *arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_last_stats_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_device_stats_t *result = 0 ; + + arg1 = (switch_device_record_t *)jarg1; + result = (switch_device_stats_t *)& ((arg1)->last_stats); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_state_set(void * jarg1, int jarg2) { switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; switch_device_state_t arg2 ; @@ -7451,6 +7842,151 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_last_call_time_get(v } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_ring_start_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->ring_start = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_ring_start_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->ring_start); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_ring_stop_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->ring_stop = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_ring_stop_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->ring_stop); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_hold_start_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->hold_start = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_hold_start_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->hold_start); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_hold_stop_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->hold_stop = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_hold_stop_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->hold_stop); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_call_start_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t arg2 ; + switch_time_t *argp2 ; + + arg1 = (switch_device_record_t *)jarg1; + argp2 = (switch_time_t *)jarg2; + if (!argp2) { + SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_time_t", 0); + return ; + } + arg2 = *argp2; + if (arg1) (arg1)->call_start = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_call_start_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + switch_time_t result; + + arg1 = (switch_device_record_t *)jarg1; + result = ((arg1)->call_start); + jresult = new switch_time_t((switch_time_t &)result); + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_uuid_list_set(void * jarg1, void * jarg2) { switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; device_uuid_node_s *arg2 = (device_uuid_node_s *) 0 ; @@ -7543,6 +8079,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_pool_get(void * jarg } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_device_record_t_user_data_set(void * jarg1, void * jarg2) { + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + void *arg2 = (void *) 0 ; + + arg1 = (switch_device_record_t *)jarg1; + arg2 = (void *)jarg2; + if (arg1) (arg1)->user_data = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_device_record_t_user_data_get(void * jarg1) { + void * jresult ; + switch_device_record_t *arg1 = (switch_device_record_t *) 0 ; + void *result = 0 ; + + arg1 = (switch_device_record_t *)jarg1; + result = (void *) ((arg1)->user_data); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_device_record_t() { void * jresult ; switch_device_record_t *result = 0 ; @@ -12579,9 +13138,9 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_time_set_monotonic(int jarg1) { SWIGEXPORT void SWIGSTDCALL CSharp_switch_time_set_timerfd(int jarg1) { - switch_bool_t arg1 ; + int arg1 ; - arg1 = (switch_bool_t)jarg1; + arg1 = (int)jarg1; switch_time_set_timerfd(arg1); } @@ -14059,6 +14618,14 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ice_direction(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_debug_pool(void * jarg1) { + switch_stream_handle_t *arg1 = (switch_stream_handle_t *) 0 ; + + arg1 = (switch_stream_handle_t *)jarg1; + switch_core_session_debug_pool(arg1); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_set(void * jarg1, char * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; char *arg2 = (char *) 0 ; @@ -18098,6 +18665,29 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_caller_profile_direction_get(void * jar } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_logical_direction_set(void * jarg1, int jarg2) { + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_call_direction_t arg2 ; + + arg1 = (switch_caller_profile *)jarg1; + arg2 = (switch_call_direction_t)jarg2; + if (arg1) (arg1)->logical_direction = arg2; + +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_caller_profile_logical_direction_get(void * jarg1) { + int jresult ; + switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; + switch_call_direction_t result; + + arg1 = (switch_caller_profile *)jarg1; + result = (switch_call_direction_t) ((arg1)->logical_direction); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_caller_profile_soft_set(void * jarg1, void * jarg2) { switch_caller_profile *arg1 = (switch_caller_profile *) 0 ; profile_node_t *arg2 = (profile_node_t *) 0 ; @@ -19101,6 +19691,29 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_frame_user_data_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_frame_pmap_set(void * jarg1, void * jarg2) { + switch_frame *arg1 = (switch_frame *) 0 ; + payload_map_t *arg2 = (payload_map_t *) 0 ; + + arg1 = (switch_frame *)jarg1; + arg2 = (payload_map_t *)jarg2; + if (arg1) (arg1)->pmap = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_frame_pmap_get(void * jarg1) { + void * jresult ; + switch_frame *arg1 = (switch_frame *) 0 ; + payload_map_t *result = 0 ; + + arg1 = (switch_frame *)jarg1; + result = (payload_map_t *) ((arg1)->pmap); + jresult = (void *)result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_frame() { void * jresult ; switch_frame *result = 0 ; @@ -29824,6 +30437,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_direction(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_channel_logical_direction(void * jarg1) { + int jresult ; + switch_channel_t *arg1 = (switch_channel_t *) 0 ; + switch_call_direction_t result; + + arg1 = (switch_channel_t *)jarg1; + result = (switch_call_direction_t)switch_channel_logical_direction(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_set_direction(void * jarg1, int jarg2) { switch_channel_t *arg1 = (switch_channel_t *) 0 ; switch_call_direction_t arg2 ; @@ -32169,6 +32794,72 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_live_array_parse_json(void * jarg1, un } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_add_alias(void * jarg1, char * jarg2, char * jarg3) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + switch_bool_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + result = (switch_bool_t)switch_live_array_add_alias(arg1,(char const *)arg2,(char const *)arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_live_array_clear_alias(void * jarg1, char * jarg2, char * jarg3) { + int jresult ; + switch_live_array_t *arg1 = (switch_live_array_t *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + switch_bool_t result; + + arg1 = (switch_live_array_t *)jarg1; + arg2 = (char *)jarg2; + arg3 = (char *)jarg3; + result = (switch_bool_t)switch_live_array_clear_alias(arg1,(char const *)arg2,(char const *)arg3); + jresult = result; + return jresult; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_event_channel_permission_verify(char * jarg1, char * jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t result; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + result = (switch_bool_t)switch_event_channel_permission_verify((char const *)arg1,(char const *)arg2); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_event_channel_permission_modify(char * jarg1, char * jarg2, int jarg3) { + char *arg1 = (char *) 0 ; + char *arg2 = (char *) 0 ; + switch_bool_t arg3 ; + + arg1 = (char *)jarg1; + arg2 = (char *)jarg2; + arg3 = (switch_bool_t)jarg3; + switch_event_channel_permission_modify((char const *)arg1,(char const *)arg2,arg3); +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_event_channel_permission_clear(char * jarg1) { + char *arg1 = (char *) 0 ; + + arg1 = (char *)jarg1; + switch_event_channel_permission_clear((char const *)arg1); +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RESAMPLE_QUALITY_get() { int jresult ; int result; @@ -36923,16 +37614,6 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_telephony_recv_event(void * ja } -SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_recv_pt(void * jarg1, unsigned char jarg2) { - switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; - switch_payload_t arg2 ; - - arg1 = (switch_rtp_t *)jarg1; - arg2 = (switch_payload_t)jarg2; - switch_rtp_set_recv_pt(arg1,arg2); -} - - SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_set_cng_pt(void * jarg1, unsigned char jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_payload_t arg2 ; @@ -36955,6 +37636,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_private(void * jarg1) { } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_set_payload_map(void * jarg1, void * jarg2) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + payload_map_t **arg2 = (payload_map_t **) 0 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + arg2 = (payload_map_t **)jarg2; + result = (switch_status_t)switch_rtp_set_payload_map(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_intentional_bugs(void * jarg1, int jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_rtp_bug_flag_t arg2 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 50ac5a3245..46c72e92d2 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -2749,8 +2749,8 @@ public class freeswitch { freeswitchPINVOKE.switch_time_set_monotonic((int)enable); } - public static void switch_time_set_timerfd(switch_bool_t enable) { - freeswitchPINVOKE.switch_time_set_timerfd((int)enable); + public static void switch_time_set_timerfd(int enable) { + freeswitchPINVOKE.switch_time_set_timerfd(enable); } public static void switch_time_set_nanosleep(switch_bool_t enable) { @@ -3146,6 +3146,10 @@ public class freeswitch { return ret; } + public static void switch_core_session_debug_pool(switch_stream_handle stream) { + freeswitchPINVOKE.switch_core_session_debug_pool(switch_stream_handle.getCPtr(stream)); + } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); return ret; @@ -4581,6 +4585,11 @@ public class freeswitch { return ret; } + public static switch_call_direction_t switch_channel_logical_direction(SWIGTYPE_p_switch_channel channel) { + switch_call_direction_t ret = (switch_call_direction_t)freeswitchPINVOKE.switch_channel_logical_direction(SWIGTYPE_p_switch_channel.getCPtr(channel)); + return ret; + } + public static void switch_channel_set_direction(SWIGTYPE_p_switch_channel channel, switch_call_direction_t direction) { freeswitchPINVOKE.switch_channel_set_direction(SWIGTYPE_p_switch_channel.getCPtr(channel), (int)direction); } @@ -5129,6 +5138,29 @@ public class freeswitch { freeswitchPINVOKE.switch_live_array_parse_json(SWIGTYPE_p_cJSON.getCPtr(json), channel_id); } + public static switch_bool_t switch_live_array_add_alias(SWIGTYPE_p_switch_live_array_s la, string event_channel, string name) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_live_array_add_alias(SWIGTYPE_p_switch_live_array_s.getCPtr(la), event_channel, name); + return ret; + } + + public static switch_bool_t switch_live_array_clear_alias(SWIGTYPE_p_switch_live_array_s la, string event_channel, string name) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_live_array_clear_alias(SWIGTYPE_p_switch_live_array_s.getCPtr(la), event_channel, name); + return ret; + } + + public static switch_bool_t switch_event_channel_permission_verify(string cookie, string event_channel) { + switch_bool_t ret = (switch_bool_t)freeswitchPINVOKE.switch_event_channel_permission_verify(cookie, event_channel); + return ret; + } + + public static void switch_event_channel_permission_modify(string cookie, string event_channel, switch_bool_t set) { + freeswitchPINVOKE.switch_event_channel_permission_modify(cookie, event_channel, (int)set); + } + + public static void switch_event_channel_permission_clear(string cookie) { + freeswitchPINVOKE.switch_event_channel_permission_clear(cookie); + } + public static switch_status_t switch_resample_perform_create(SWIGTYPE_p_p_switch_audio_resampler_t new_resampler, uint from_rate, uint to_rate, uint to_size, int quality, uint channels, string file, string func, int line) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_resample_perform_create(SWIGTYPE_p_p_switch_audio_resampler_t.getCPtr(new_resampler), from_rate, to_rate, to_size, quality, channels, file, func, line); return ret; @@ -6197,10 +6229,6 @@ public class freeswitch { freeswitchPINVOKE.switch_rtp_set_telephony_recv_event(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), te); } - public static void switch_rtp_set_recv_pt(SWIGTYPE_p_switch_rtp rtp_session, byte pt) { - freeswitchPINVOKE.switch_rtp_set_recv_pt(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), pt); - } - public static void switch_rtp_set_cng_pt(SWIGTYPE_p_switch_rtp rtp_session, byte pt) { freeswitchPINVOKE.switch_rtp_set_cng_pt(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), pt); } @@ -6211,6 +6239,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_rtp_set_payload_map(SWIGTYPE_p_switch_rtp rtp_session, SWIGTYPE_p_p_payload_map_t pmap) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_set_payload_map(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), SWIGTYPE_p_p_payload_map_t.getCPtr(pmap)); + return ret; + } + public static void switch_rtp_intentional_bugs(SWIGTYPE_p_switch_rtp rtp_session, switch_rtp_bug_flag_t bugs) { freeswitchPINVOKE.switch_rtp_intentional_bugs(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)bugs); } @@ -8903,6 +8936,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_hup_profile_get")] public static extern IntPtr switch_device_node_t_hup_profile_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_direction_set")] + public static extern void switch_device_node_t_direction_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_direction_get")] + public static extern int switch_device_node_t_direction_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_node_t_parent_set")] public static extern void switch_device_node_t_parent_set(HandleRef jarg1, HandleRef jarg2); @@ -8927,42 +8966,132 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_get")] public static extern uint switch_device_stats_t_total_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_in_set")] + public static extern void switch_device_stats_t_total_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_in_get")] + public static extern uint switch_device_stats_t_total_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_out_set")] + public static extern void switch_device_stats_t_total_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_total_out_get")] + public static extern uint switch_device_stats_t_total_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_set")] public static extern void switch_device_stats_t_offhook_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_get")] public static extern uint switch_device_stats_t_offhook_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_in_set")] + public static extern void switch_device_stats_t_offhook_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_in_get")] + public static extern uint switch_device_stats_t_offhook_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_out_set")] + public static extern void switch_device_stats_t_offhook_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_offhook_out_get")] + public static extern uint switch_device_stats_t_offhook_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_set")] public static extern void switch_device_stats_t_active_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_get")] public static extern uint switch_device_stats_t_active_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_in_set")] + public static extern void switch_device_stats_t_active_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_in_get")] + public static extern uint switch_device_stats_t_active_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_out_set")] + public static extern void switch_device_stats_t_active_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_active_out_get")] + public static extern uint switch_device_stats_t_active_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_set")] public static extern void switch_device_stats_t_held_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_get")] public static extern uint switch_device_stats_t_held_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_in_set")] + public static extern void switch_device_stats_t_held_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_in_get")] + public static extern uint switch_device_stats_t_held_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_out_set")] + public static extern void switch_device_stats_t_held_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_held_out_get")] + public static extern uint switch_device_stats_t_held_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_set")] public static extern void switch_device_stats_t_hup_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_get")] public static extern uint switch_device_stats_t_hup_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_in_set")] + public static extern void switch_device_stats_t_hup_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_in_get")] + public static extern uint switch_device_stats_t_hup_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_out_set")] + public static extern void switch_device_stats_t_hup_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_hup_out_get")] + public static extern uint switch_device_stats_t_hup_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_set")] public static extern void switch_device_stats_t_ringing_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_get")] public static extern uint switch_device_stats_t_ringing_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_in_set")] + public static extern void switch_device_stats_t_ringing_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_in_get")] + public static extern uint switch_device_stats_t_ringing_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_out_set")] + public static extern void switch_device_stats_t_ringing_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ringing_out_get")] + public static extern uint switch_device_stats_t_ringing_out_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_set")] public static extern void switch_device_stats_t_early_set(HandleRef jarg1, uint jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_get")] public static extern uint switch_device_stats_t_early_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_in_set")] + public static extern void switch_device_stats_t_early_in_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_in_get")] + public static extern uint switch_device_stats_t_early_in_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_out_set")] + public static extern void switch_device_stats_t_early_out_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_early_out_get")] + public static extern uint switch_device_stats_t_early_out_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ring_wait_set")] + public static extern void switch_device_stats_t_ring_wait_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_stats_t_ring_wait_get")] + public static extern uint switch_device_stats_t_ring_wait_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_device_stats_t")] public static extern IntPtr new_switch_device_stats_t(); @@ -8993,6 +9122,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_stats_get")] public static extern IntPtr switch_device_record_t_stats_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_last_stats_set")] + public static extern void switch_device_record_t_last_stats_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_last_stats_get")] + public static extern IntPtr switch_device_record_t_last_stats_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_state_set")] public static extern void switch_device_record_t_state_set(HandleRef jarg1, int jarg2); @@ -9023,6 +9158,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_last_call_time_get")] public static extern IntPtr switch_device_record_t_last_call_time_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_start_set")] + public static extern void switch_device_record_t_ring_start_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_start_get")] + public static extern IntPtr switch_device_record_t_ring_start_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_stop_set")] + public static extern void switch_device_record_t_ring_stop_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_ring_stop_get")] + public static extern IntPtr switch_device_record_t_ring_stop_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_start_set")] + public static extern void switch_device_record_t_hold_start_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_start_get")] + public static extern IntPtr switch_device_record_t_hold_start_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_stop_set")] + public static extern void switch_device_record_t_hold_stop_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_hold_stop_get")] + public static extern IntPtr switch_device_record_t_hold_stop_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_call_start_set")] + public static extern void switch_device_record_t_call_start_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_call_start_get")] + public static extern IntPtr switch_device_record_t_call_start_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_uuid_list_set")] public static extern void switch_device_record_t_uuid_list_set(HandleRef jarg1, HandleRef jarg2); @@ -9047,6 +9212,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_pool_get")] public static extern IntPtr switch_device_record_t_pool_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_user_data_set")] + public static extern void switch_device_record_t_user_data_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_device_record_t_user_data_get")] + public static extern IntPtr switch_device_record_t_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_device_record_t")] public static extern IntPtr new_switch_device_record_t(); @@ -10538,6 +10709,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ice_direction")] public static extern int switch_ice_direction(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_debug_pool")] + public static extern void switch_core_session_debug_pool(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); @@ -11426,6 +11600,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_direction_get")] public static extern int switch_caller_profile_direction_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_logical_direction_set")] + public static extern void switch_caller_profile_logical_direction_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_logical_direction_get")] + public static extern int switch_caller_profile_logical_direction_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_caller_profile_soft_set")] public static extern void switch_caller_profile_soft_set(HandleRef jarg1, HandleRef jarg2); @@ -11663,6 +11843,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_user_data_get")] public static extern IntPtr switch_frame_user_data_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_pmap_set")] + public static extern void switch_frame_pmap_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_frame_pmap_get")] + public static extern IntPtr switch_frame_pmap_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_frame")] public static extern IntPtr new_switch_frame(); @@ -14327,6 +14513,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_direction")] public static extern int switch_channel_direction(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_logical_direction")] + public static extern int switch_channel_logical_direction(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_set_direction")] public static extern void switch_channel_set_direction(HandleRef jarg1, int jarg2); @@ -14849,6 +15038,21 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_parse_json")] public static extern void switch_live_array_parse_json(HandleRef jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_add_alias")] + public static extern int switch_live_array_add_alias(HandleRef jarg1, string jarg2, string jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_live_array_clear_alias")] + public static extern int switch_live_array_clear_alias(HandleRef jarg1, string jarg2, string jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_permission_verify")] + public static extern int switch_event_channel_permission_verify(string jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_permission_modify")] + public static extern void switch_event_channel_permission_modify(string jarg1, string jarg2, int jarg3); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_event_channel_permission_clear")] + public static extern void switch_event_channel_permission_clear(string jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RESAMPLE_QUALITY_get")] public static extern int SWITCH_RESAMPLE_QUALITY_get(); @@ -15836,15 +16040,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_telephony_recv_event")] public static extern void switch_rtp_set_telephony_recv_event(HandleRef jarg1, byte jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_recv_pt")] - public static extern void switch_rtp_set_recv_pt(HandleRef jarg1, byte jarg2); - [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_cng_pt")] public static extern void switch_rtp_set_cng_pt(HandleRef jarg1, byte jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_private")] public static extern IntPtr switch_rtp_get_private(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_payload_map")] + public static extern int switch_rtp_set_payload_map(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_intentional_bugs")] public static extern void switch_rtp_intentional_bugs(HandleRef jarg1, int jarg2); @@ -20882,6 +21086,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_payload_map_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_payload_map_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_payload_map_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_payload_map_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_char { private HandleRef swigCPtr; @@ -20972,6 +21206,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_p_payload_map_t { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_p_payload_map_t(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_p_payload_map_t() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_p_payload_map_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_p_p_char { private HandleRef swigCPtr; @@ -26140,6 +26404,16 @@ public class switch_caller_profile : IDisposable { } } + public switch_call_direction_t logical_direction { + set { + freeswitchPINVOKE.switch_caller_profile_logical_direction_set(swigCPtr, (int)value); + } + get { + switch_call_direction_t ret = (switch_call_direction_t)freeswitchPINVOKE.switch_caller_profile_logical_direction_get(swigCPtr); + return ret; + } + } + public profile_node_t soft { set { freeswitchPINVOKE.switch_caller_profile_soft_set(swigCPtr, profile_node_t.getCPtr(value)); @@ -26241,6 +26515,7 @@ public enum switch_channel_callstate_t { CCS_EARLY, CCS_ACTIVE, CCS_HELD, + CCS_RING_WAIT, CCS_HANGUP, CCS_UNHOLD } @@ -26360,6 +26635,7 @@ public enum switch_channel_flag_t { CF_CONFIRM_BLIND_TRANSFER, CF_NO_PRESENCE, CF_CONFERENCE, + CF_CONFERENCE_ADV, CF_RECOVERING, CF_RECOVERING_BRIDGE, CF_TRACKED, @@ -26393,6 +26669,7 @@ public enum switch_channel_flag_t { CF_VIDEO_ECHO, CF_SLA_INTERCEPT, CF_VIDEO_BREAK, + CF_MEDIA_PAUSE, CF_FLAG_MAX } @@ -28314,6 +28591,7 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE, SWITCH_MESSAGE_INDICATE_STUN_ERROR, SWITCH_MESSAGE_INDICATE_MEDIA_RENEG, + SWITCH_MESSAGE_REFER_EVENT, SWITCH_MESSAGE_ANSWER_EVENT, SWITCH_MESSAGE_PROGRESS_EVENT, SWITCH_MESSAGE_RING_EVENT, @@ -28644,6 +28922,16 @@ public class switch_device_node_t : IDisposable { } } + public switch_call_direction_t direction { + set { + freeswitchPINVOKE.switch_device_node_t_direction_set(swigCPtr, (int)value); + } + get { + switch_call_direction_t ret = (switch_call_direction_t)freeswitchPINVOKE.switch_device_node_t_direction_get(swigCPtr); + return ret; + } + } + public switch_device_record_t parent { set { freeswitchPINVOKE.switch_device_node_t_parent_set(swigCPtr, switch_device_record_t.getCPtr(value)); @@ -28754,6 +29042,17 @@ public class switch_device_record_t : IDisposable { } } + public switch_device_stats_t last_stats { + set { + freeswitchPINVOKE.switch_device_record_t_last_stats_set(swigCPtr, switch_device_stats_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_device_record_t_last_stats_get(swigCPtr); + switch_device_stats_t ret = (cPtr == IntPtr.Zero) ? null : new switch_device_stats_t(cPtr, false); + return ret; + } + } + public switch_device_state_t state { set { freeswitchPINVOKE.switch_device_record_t_state_set(swigCPtr, (int)value); @@ -28810,6 +29109,66 @@ public class switch_device_record_t : IDisposable { } } + public SWIGTYPE_p_switch_time_t ring_start { + set { + freeswitchPINVOKE.switch_device_record_t_ring_start_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_ring_start_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t ring_stop { + set { + freeswitchPINVOKE.switch_device_record_t_ring_stop_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_ring_stop_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t hold_start { + set { + freeswitchPINVOKE.switch_device_record_t_hold_start_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_hold_start_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t hold_stop { + set { + freeswitchPINVOKE.switch_device_record_t_hold_stop_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_hold_stop_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + + public SWIGTYPE_p_switch_time_t call_start { + set { + freeswitchPINVOKE.switch_device_record_t_call_start_set(swigCPtr, SWIGTYPE_p_switch_time_t.getCPtr(value)); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + } + get { + SWIGTYPE_p_switch_time_t ret = new SWIGTYPE_p_switch_time_t(freeswitchPINVOKE.switch_device_record_t_call_start_get(swigCPtr), true); + if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve(); + return ret; + } + } + public switch_device_node_t uuid_list { set { freeswitchPINVOKE.switch_device_record_t_uuid_list_set(swigCPtr, switch_device_node_t.getCPtr(value)); @@ -28854,6 +29213,17 @@ public class switch_device_record_t : IDisposable { } } + public SWIGTYPE_p_void user_data { + set { + freeswitchPINVOKE.switch_device_record_t_user_data_set(swigCPtr, SWIGTYPE_p_void.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_device_record_t_user_data_get(swigCPtr); + SWIGTYPE_p_void ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_void(cPtr, false); + return ret; + } + } + public switch_device_record_t() : this(freeswitchPINVOKE.new_switch_device_record_t(), true) { } @@ -28931,6 +29301,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint total_in { + set { + freeswitchPINVOKE.switch_device_stats_t_total_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_total_in_get(swigCPtr); + return ret; + } + } + + public uint total_out { + set { + freeswitchPINVOKE.switch_device_stats_t_total_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_total_out_get(swigCPtr); + return ret; + } + } + public uint offhook { set { freeswitchPINVOKE.switch_device_stats_t_offhook_set(swigCPtr, value); @@ -28941,6 +29331,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint offhook_in { + set { + freeswitchPINVOKE.switch_device_stats_t_offhook_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_offhook_in_get(swigCPtr); + return ret; + } + } + + public uint offhook_out { + set { + freeswitchPINVOKE.switch_device_stats_t_offhook_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_offhook_out_get(swigCPtr); + return ret; + } + } + public uint active { set { freeswitchPINVOKE.switch_device_stats_t_active_set(swigCPtr, value); @@ -28951,6 +29361,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint active_in { + set { + freeswitchPINVOKE.switch_device_stats_t_active_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_active_in_get(swigCPtr); + return ret; + } + } + + public uint active_out { + set { + freeswitchPINVOKE.switch_device_stats_t_active_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_active_out_get(swigCPtr); + return ret; + } + } + public uint held { set { freeswitchPINVOKE.switch_device_stats_t_held_set(swigCPtr, value); @@ -28961,6 +29391,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint held_in { + set { + freeswitchPINVOKE.switch_device_stats_t_held_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_held_in_get(swigCPtr); + return ret; + } + } + + public uint held_out { + set { + freeswitchPINVOKE.switch_device_stats_t_held_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_held_out_get(swigCPtr); + return ret; + } + } + public uint hup { set { freeswitchPINVOKE.switch_device_stats_t_hup_set(swigCPtr, value); @@ -28971,6 +29421,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint hup_in { + set { + freeswitchPINVOKE.switch_device_stats_t_hup_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_hup_in_get(swigCPtr); + return ret; + } + } + + public uint hup_out { + set { + freeswitchPINVOKE.switch_device_stats_t_hup_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_hup_out_get(swigCPtr); + return ret; + } + } + public uint ringing { set { freeswitchPINVOKE.switch_device_stats_t_ringing_set(swigCPtr, value); @@ -28981,6 +29451,26 @@ public class switch_device_stats_t : IDisposable { } } + public uint ringing_in { + set { + freeswitchPINVOKE.switch_device_stats_t_ringing_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_ringing_in_get(swigCPtr); + return ret; + } + } + + public uint ringing_out { + set { + freeswitchPINVOKE.switch_device_stats_t_ringing_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_ringing_out_get(swigCPtr); + return ret; + } + } + public uint early { set { freeswitchPINVOKE.switch_device_stats_t_early_set(swigCPtr, value); @@ -28991,6 +29481,36 @@ public class switch_device_stats_t : IDisposable { } } + public uint early_in { + set { + freeswitchPINVOKE.switch_device_stats_t_early_in_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_early_in_get(swigCPtr); + return ret; + } + } + + public uint early_out { + set { + freeswitchPINVOKE.switch_device_stats_t_early_out_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_early_out_get(swigCPtr); + return ret; + } + } + + public uint ring_wait { + set { + freeswitchPINVOKE.switch_device_stats_t_ring_wait_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_device_stats_t_ring_wait_get(swigCPtr); + return ret; + } + } + public switch_device_stats_t() : this(freeswitchPINVOKE.new_switch_device_stats_t(), true) { } @@ -31337,6 +31857,17 @@ public class switch_frame : IDisposable { } } + public SWIGTYPE_p_payload_map_t pmap { + set { + freeswitchPINVOKE.switch_frame_pmap_set(swigCPtr, SWIGTYPE_p_payload_map_t.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_frame_pmap_get(swigCPtr); + SWIGTYPE_p_payload_map_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_payload_map_t(cPtr, false); + return ret; + } + } + public switch_frame() : this(freeswitchPINVOKE.new_switch_frame(), true) { } @@ -34147,9 +34678,11 @@ namespace FreeSWITCH.Native { SOF_NONE = 0, SOF_NOBLOCK = (1 << 0), SOF_FORKED_DIAL = (1 << 1), - SOF_NO_EFFECTIVE_CID_NUM = (1 << 2), - SOF_NO_EFFECTIVE_CID_NAME = (1 << 3), - SOF_NO_LIMITS = (1 << 4) + SOF_NO_EFFECTIVE_ANI = (1 << 2), + SOF_NO_EFFECTIVE_ANIII = (1 << 3), + SOF_NO_EFFECTIVE_CID_NUM = (1 << 4), + SOF_NO_EFFECTIVE_CID_NAME = (1 << 5), + SOF_NO_LIMITS = (1 << 6) } } @@ -34605,6 +35138,9 @@ public enum switch_rtp_flag_t { SWITCH_RTP_FLAG_RTCP_MUX, SWITCH_RTP_FLAG_KILL_JB, SWITCH_RTP_FLAG_VIDEO_BREAK, + SWITCH_RTP_FLAG_PAUSE, + SWITCH_RTP_FLAG_FIR, + SWITCH_RTP_FLAG_PLI, SWITCH_RTP_FLAG_INVALID } From 0221403514d2f364b9dc5d738d7ad5eeee183a8a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 23 Nov 2013 03:21:25 +0500 Subject: [PATCH 133/656] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 42256e2dda..e445e34776 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.5.7b], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.5.7], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [5]) -AC_SUBST(SWITCH_VERSION_MICRO, [7b]) +AC_SUBST(SWITCH_VERSION_MICRO, [7]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From 2cd5841cd44e26942668b1213515bae3469ba338 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 23 Nov 2013 03:23:01 +0500 Subject: [PATCH 134/656] bump --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index e445e34776..e27d3d860a 100644 --- a/configure.in +++ b/configure.in @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.5.7], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.5.8b], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [5]) -AC_SUBST(SWITCH_VERSION_MICRO, [7]) +AC_SUBST(SWITCH_VERSION_MICRO, [8b]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) From ed69ca80dec4cd6ae861a8781a32b0edd2be0cec Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 23 Nov 2013 19:23:11 -0600 Subject: [PATCH 135/656] fix compile --- src/mod/applications/mod_fifo/mod_fifo.c | 48 ++++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 4ba7b01f78..b993756963 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -2258,15 +2258,15 @@ static void dec_use_count(switch_core_session_t *session, const char *type) } hold_usec = originator_cp->times->hold_accum; tt_usec = (switch_micro_time_now() - originator_cp->times->bridged) - hold_usec; - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-us", "%lu", originator_cp->times->bridged); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-ms", "%lu", (uint64_t)(originator_cp->times->bridged / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-s", "%lu", (uint64_t)(originator_cp->times->bridged / 1000000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-us", "%lu", tt_usec); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-ms", "%lu", (uint64_t)(tt_usec / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-s", "%lu", (uint64_t)(tt_usec / 1000000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-us", "%lu", hold_usec); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-ms", "%lu", (uint64_t)(hold_usec / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-s", "%lu", (uint64_t)(hold_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-us", "%"SWITCH_TIME_T_FMT, originator_cp->times->bridged); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(originator_cp->times->bridged / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(originator_cp->times->bridged / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-us", "%"SWITCH_TIME_T_FMT, tt_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(tt_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(tt_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-us", "%"SWITCH_TIME_T_FMT, hold_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000000)); switch_event_fire(&event); } @@ -3287,15 +3287,15 @@ SWITCH_STANDARD_APP(fifo_function) } hold_usec = originator_cp->times->hold_accum; tt_usec = (switch_micro_time_now() - originator_cp->times->bridged) - hold_usec; - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-us", "%lu", originator_cp->times->bridged); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-ms", "%lu", (uint64_t)(originator_cp->times->bridged / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-s", "%lu", (uint64_t)(originator_cp->times->bridged / 1000000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-us", "%lu", tt_usec); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-ms", "%lu", (uint64_t)(tt_usec / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-s", "%lu", (uint64_t)(tt_usec / 1000000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-us", "%lu", hold_usec); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-ms", "%lu", (uint64_t)(hold_usec / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-s", "%lu", (uint64_t)(hold_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-us", "%"SWITCH_TIME_T_FMT, originator_cp->times->bridged); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(originator_cp->times->bridged / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Bridge-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(originator_cp->times->bridged / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-us", "%"SWITCH_TIME_T_FMT, tt_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(tt_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Talk-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(tt_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-us", "%"SWITCH_TIME_T_FMT, hold_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000000)); switch_event_fire(&event); } @@ -3321,12 +3321,12 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "bridge-caller-stop"); hold_usec = originatee_cp->times->hold_accum; tt_usec = (switch_micro_time_now() - originatee_cp->times->bridged) - hold_usec; - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-us", "%lu", tt_usec); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-ms", "%lu", (uint64_t)(tt_usec / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-s", "%lu", (uint64_t)(tt_usec / 1000000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-us", "%lu", hold_usec); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-ms", "%lu", (uint64_t)(hold_usec / 1000)); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-s", "%lu", (uint64_t)(hold_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-us", "%"SWITCH_TIME_T_FMT, tt_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(tt_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Talk-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(tt_usec / 1000000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-us", "%"SWITCH_TIME_T_FMT, hold_usec); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Caller-Hold-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000000)); switch_event_fire(&event); } From aa8a4913b4c7d9436cde45075e0d9df07096ca51 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 23 Nov 2013 20:11:59 -0600 Subject: [PATCH 136/656] FS-5994 --- src/switch_ivr_bridge.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 089301da0e..ffc7e0b5e8 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -976,18 +976,12 @@ static switch_status_t sb_on_dtmf(switch_core_session_t *session, const switch_d static switch_status_t hanguphook(switch_core_session_t *session) { - switch_core_session_message_t msg = { 0 }; + switch_core_session_message_t *msg = NULL; switch_channel_t *channel = NULL; switch_event_t *event; channel = switch_core_session_get_channel(session); - - msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; - msg.from = __FILE__; - msg.string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE); - - if (switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { switch_channel_clear_flag_recursive(channel, CF_BRIDGE_ORIGINATOR); if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { @@ -996,8 +990,14 @@ static switch_status_t hanguphook(switch_core_session_t *session) } } + + msg = switch_core_session_alloc(session, sizeof(*msg)); + MESSAGE_STAMP_FFL(msg); + msg->message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; + msg->from = __FILE__; + msg->string_arg = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE); + switch_core_session_queue_message(session, msg); - switch_core_session_receive_message(session, &msg); switch_core_event_hook_remove_state_change(session, hanguphook); return SWITCH_STATUS_SUCCESS; From 27476602696e1a2dea1beea88091bb22fcefeb9d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 25 Nov 2013 12:08:17 -0600 Subject: [PATCH 137/656] FS-5959 FS-5958 --- src/mod/endpoints/mod_sofia/sofia.c | 2 +- src/switch_core_media.c | 12 +++++++++++- src/switch_rtp.c | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index cd566c22bd..f9fc330c71 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6478,7 +6478,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); if (tech_pvt->mparams.num_codecs) { - match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); + match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); } if (match) { if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 25af9b4e29..873519eb11 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -497,6 +497,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core recv_pt = pmap->recv_pt; fmtp = pmap->rm_fmtp; found++; + break; } } switch_mutex_unlock(smh->sdp_mutex); @@ -602,7 +603,12 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se if (sdp_type == SDP_TYPE_REQUEST || !exists) { + int b4 = pmap->pt; pmap->pt = (switch_payload_t) (local_pt ? local_pt : pt); + + if (b4 == 97 && pmap->pt == 109) { + abort(); + } } if (negotiated) { @@ -6354,7 +6360,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp"); } } - + if (pass_fmtp) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\n", v_engine->cur_payload_map->pt, pass_fmtp); } @@ -6433,6 +6439,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess fmtp = switch_event_get_header(map, imp->iananame); } + if (smh->fmtps[i]) { + fmtp = smh->fmtps[i]; + } + if (zstr(fmtp)) fmtp = imp->fmtp; if (zstr(fmtp)) fmtp = (char *) pass_fmtp; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 490137e08b..6e6c594f05 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5047,6 +5047,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ payload_map_t *pmap; switch_mutex_lock(rtp_session->flag_mutex); for (pmap = *rtp_session->pmaps; pmap && pmap->allocated; pmap = pmap->next) { + if (!pmap->negotiated) { continue; } @@ -5056,6 +5057,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (pmapP) { *pmapP = pmap; } + break; } } switch_mutex_unlock(rtp_session->flag_mutex); @@ -5064,6 +5066,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (!accept_packet && !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PAYLOAD) && !(rtp_session->rtp_bugs & RTP_BUG_ACCEPT_ANY_PACKETS)) { /* drop frames of incorrect payload number and return CNG frame instead */ + return_cng_frame(); } } From 1e59690cc17bbe9072bd14b11a1c97e489dd1d35 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 25 Nov 2013 12:34:04 -0600 Subject: [PATCH 138/656] FS-6001 --resolve --- src/mod/applications/mod_commands/mod_commands.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 019e3f8563..7956903c38 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1946,6 +1946,16 @@ SWITCH_STANDARD_API(cond_function) } } + if (strspn(a, "!<>=")) { + expr = a; + } + + if (expr == a) { + a = ""; + } + + while (*expr == ' ') expr++; + while(expr && *expr) { switch(*expr) { case '!': From 00f52f30021dd2d74812427c1e724e076748d2c9 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 25 Nov 2013 16:09:12 -0600 Subject: [PATCH 139/656] FS-4965 calling the variable playback_last_offset_pos instead --- src/switch_ivr_play_say.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 3d7894ff74..1d44342ca3 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1721,6 +1721,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done playing file %s\n", file); + switch_channel_set_variable_printf(channel, "playback_last_offset_pos", "%d", fh->offset_pos); if (read_impl.samples_per_second) { switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_in / fh->native_rate); From 83ccceb2b5e8f9d8033006a153aca022665fd971 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 26 Nov 2013 10:04:29 -0600 Subject: [PATCH 140/656] FS-5958 remove debug --- src/switch_core_media.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 873519eb11..790ea0f5bc 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -605,10 +605,6 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se if (sdp_type == SDP_TYPE_REQUEST || !exists) { int b4 = pmap->pt; pmap->pt = (switch_payload_t) (local_pt ? local_pt : pt); - - if (b4 == 97 && pmap->pt == 109) { - abort(); - } } if (negotiated) { From c56b73d0be53c87a7fb12edef1b186267cb428d3 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 26 Nov 2013 17:15:14 +0000 Subject: [PATCH 141/656] remove unused variable --- src/switch_core_media.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 790ea0f5bc..a8336dd03b 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -603,7 +603,6 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se if (sdp_type == SDP_TYPE_REQUEST || !exists) { - int b4 = pmap->pt; pmap->pt = (switch_payload_t) (local_pt ? local_pt : pt); } From beb0673f259788a239e5e44162e8b1e2c765dd64 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Tue, 26 Nov 2013 19:38:30 -0500 Subject: [PATCH 142/656] expose useful internals... thanks jaybinks --- src/switch_ivr_play_say.c | 138 ++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 66 deletions(-) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 1d44342ca3..97f553d733 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1,4 +1,4 @@ -/* +/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005-2012, Anthony Minessale II * @@ -22,7 +22,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * + * * Anthony Minessale II * Paul D. Tinsley * Neal Horman @@ -314,12 +314,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro_event(switch_core_sessio switch_ivr_sleep(session, pause, SWITCH_FALSE, NULL); switch_safe_free(expanded); switch_safe_free(substituted); - + } } switch_regex_safe_free(re); - + if ((match && do_break && switch_true(do_break)) || status == SWITCH_STATUS_BREAK) { break; } @@ -438,7 +438,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se } } - + if ((vval = switch_channel_get_variable(channel, "record_fill_cng"))) { if (!strcasecmp(vval, "true")) { @@ -449,7 +449,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se } } } - + if ((vval = switch_channel_get_variable(channel, "record_waste_resources"))) { @@ -539,7 +539,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (sample_start > 0) { uint32_t pos = 0; switch_core_file_seek(fh, &pos, sample_start, SEEK_SET); - switch_clear_flag(fh, SWITCH_FILE_SEEK); + switch_clear_flag(fh, SWITCH_FILE_SEEK); fh->samples = 0; } @@ -547,7 +547,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) { asis = 1; } - + restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf")); if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) { @@ -655,7 +655,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (args) { /* - dtmf handler function you can hook up to be executed when a digit is dialed during playback + dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { @@ -675,7 +675,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { break; } - } + } if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); @@ -693,7 +693,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if ((ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { status = ostatus; } - + switch_event_destroy(&event); } } @@ -760,7 +760,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se len = write_frame.datalen / 2; if (switch_core_file_write(fh, write_frame.data, &len) != SWITCH_STATUS_SUCCESS) { break; - } + } } if (waste_resources) { @@ -782,22 +782,22 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se char *cmd = switch_core_session_strdup(session, var); char *data, *expanded = NULL; switch_stream_handle_t stream = { 0 }; - + SWITCH_STANDARD_STREAM(stream); - + if ((data = strchr(cmd, ':'))) { *data++ = '\0'; expanded = switch_channel_expand_variables(channel, data); } - + switch_api_execute(cmd, expanded, session, &stream); - + if (expanded && expanded != data) { free(expanded); } - + switch_safe_free(stream.data); - + } if (read_impl.actual_samples_per_second) { @@ -916,7 +916,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi if (args) { /* - dtmf handler function you can hook up to be executed when a digit is dialed during gentones + dtmf handler function you can hook up to be executed when a digit is dialed during gentones if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { @@ -931,7 +931,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { break; } - } + } if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); @@ -943,7 +943,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi if (args->input_callback) { switch_event_t *event; - + if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); if (ostatus != SWITCH_STATUS_SUCCESS) { @@ -985,7 +985,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_get_file_handle(switch_core_session_t *fh = NULL; switch_core_session_io_read_lock(session); - + if ((fhp = switch_channel_get_private(channel, "__fh"))) { *fh = fhp; return SWITCH_STATUS_SUCCESS; @@ -1105,12 +1105,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess fh = &lfh; memset(fh, 0, sizeof(lfh)); } - + if (fh->samples > 0) { sample_start = fh->samples; fh->samples = 0; } - + @@ -1122,9 +1122,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess fh->samples = sample_start = 0; if (sleep_val_i) { status = switch_ivr_sleep(session, sleep_val_i, SWITCH_FALSE, args); - if(status != SWITCH_STATUS_SUCCESS) { - break; - } + if(status != SWITCH_STATUS_SUCCESS) { + break; + } } } @@ -1300,7 +1300,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess //date = switch_core_session_strdup(session, p); switch_channel_set_variable(channel, "RECORD_DATE", p); } - + interval = read_impl.microseconds_per_packet / 1000; if (!fh->audio_buffer) { @@ -1309,7 +1309,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } codec_name = "L16"; - + if (!switch_core_codec_ready((&codec))) { if (switch_core_codec_init(&codec, codec_name, @@ -1318,17 +1318,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval); - - + + } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval); switch_core_session_io_write_lock(session); switch_channel_set_private(channel, "__fh", NULL); switch_core_session_io_rwunlock(session); - + switch_core_file_close(fh); - + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE); status = SWITCH_STATUS_GENERR; continue; @@ -1346,7 +1346,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess samples = codec.implementation->samples_per_packet; framelen = codec.implementation->decoded_bytes_per_packet; } - + last_native = test_native; if (timer_name && !timer.samplecount) { @@ -1395,7 +1395,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess int do_speed = 1; int last_speed = -1; int f; - + if (!switch_channel_ready(channel)) { status = SWITCH_STATUS_FALSE; break; @@ -1414,7 +1414,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if (args) { /* - dtmf handler function you can hook up to be executed when a digit is dialed during playback + dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { @@ -1430,7 +1430,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { break; } - } + } if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); @@ -1523,14 +1523,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess eof++; continue; } - + test_native = switch_test_flag(fh, SWITCH_FILE_NATIVE); if (test_native != last_native) { if (test_native) { write_frame.codec = switch_core_session_get_read_codec(session); samples = read_impl.samples_per_packet; - framelen = read_impl.encoded_bytes_per_packet; + framelen = read_impl.encoded_bytes_per_packet; } else { write_frame.codec = &codec; samples = codec.implementation->samples_per_packet; @@ -1616,7 +1616,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess last_speed = fh->speed; continue; } - + if (olen < llen) { uint8_t *dp = (uint8_t *) write_frame.data; memset(dp + (int) olen, 255, (int) (llen - olen)); @@ -1631,7 +1631,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess } else { /* time off the channel (if you must) */ switch_frame_t *read_frame; switch_status_t tstatus; - + while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) { switch_ivr_parse_all_messages(session); switch_yield(10000); @@ -1704,7 +1704,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess break; } } - + if (status == SWITCH_STATUS_MORE_DATA) { status = SWITCH_STATUS_SUCCESS; @@ -1854,26 +1854,32 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_ if (sample_count) { sample_count -= raw_codec.implementation->samples_per_packet; if (sample_count <= 0) { + switch_channel_set_variable(channel, "wait_for_silence_timeout", "true"); + switch_channel_set_variable_printf(channel, "wait_for_silence_listenhits", "%d", listening); + switch_channel_set_variable_printf(channel, "wait_for_silence_silence_hits", "%d", silence_hits); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_wait_for_silence: TIMEOUT %d\n", countdown); break; } } - + if (abuf) { switch_size_t olen = raw_codec.implementation->samples_per_packet; - + if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { break; } - + write_frame.samples = (uint32_t) olen; write_frame.datalen = (uint32_t) (olen * sizeof(int16_t)); if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) { break; } } - + if (countdown) { if (!--countdown) { + switch_channel_set_variable(channel, "wait_for_silence_timeout", "false"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_wait_for_silence: SILENCE DETECTED\n"); break; } else { continue; @@ -1920,9 +1926,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, uint32_t max_digits, const char *prompt_audio_file, const char *var_name, - char *digit_buffer, - switch_size_t digit_buffer_length, - uint32_t timeout, + char *digit_buffer, + switch_size_t digit_buffer_length, + uint32_t timeout, const char *valid_terminators, uint32_t digit_timeout) @@ -1933,7 +1939,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, size_t len = 0; char tb[2] = ""; int term_required = 0; - + if (valid_terminators && *valid_terminators == '=') { term_required = 1; @@ -1986,7 +1992,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, if ((min_digits && len < min_digits) || len < max_digits) { args.buf = digit_buffer + len; args.buflen = (uint32_t) (digit_buffer_length - len); - status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], + status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], len ? digit_timeout : timeout, digit_timeout, 0); } @@ -2049,8 +2055,8 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t const char *prompt_audio_file, const char *bad_input_audio_file, const char *var_name, - char *digit_buffer, - uint32_t digit_buffer_length, + char *digit_buffer, + uint32_t digit_buffer_length, const char *digits_regex, uint32_t digit_timeout, const char *transfer_on_failure) @@ -2103,10 +2109,10 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t } memset(digit_buffer, 0, digit_buffer_length); - + /* If we get here then check for transfer-on-failure ext/dp/context */ /* split this arg on spaces to get ext, dp, and context */ - + if (!zstr(transfer_on_failure)) { const char *failure_ext = NULL; const char *failure_dialplan = NULL; @@ -2114,18 +2120,18 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t char *target[4]; char *mydata = switch_core_session_strdup(session, transfer_on_failure); int argc; - + argc = switch_separate_string(mydata, ' ', target, (sizeof(target) / sizeof(target[0]))); - + if ( argc < 1 ) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Bad target for PAGD failure: [%s]\n", transfer_on_failure); return SWITCH_STATUS_FALSE; } - + if ( argc > 0 ) { failure_ext = target[0]; } - + if ( argc > 1 ) { failure_dialplan = target[1]; } @@ -2134,14 +2140,14 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t failure_context = target[2]; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "PAGD failure! Transfer to: %s / %s / %s\n", failure_ext, failure_dialplan, failure_context); - + switch_ivr_session_transfer(session,failure_ext, failure_dialplan, failure_context); return SWITCH_STATUS_FALSE; - } - - return SWITCH_STATUS_FALSE; + } + + return SWITCH_STATUS_FALSE; } SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session_t *session, @@ -2276,7 +2282,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session } if (args) { - /* dtmf handler function you can hook up to be executed when a digit is dialed during playback + /* dtmf handler function you can hook up to be executed when a digit is dialed during playback * if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { @@ -2295,7 +2301,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { break; } - } + } if (args->input_callback) { status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); From c62db1a600de4edadceebc9e460d2e2d50dc12c9 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 27 Nov 2013 09:51:33 -0500 Subject: [PATCH 143/656] freetdm: ftmod_wanpipe: Remove chatty debug msg, not really useful anyways --- libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index 83dbd62210..a7ac119486 100755 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -1397,7 +1397,6 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) * on at application startup, until that is fixed we check the link status here too */ ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status); ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? FTDM_ALARM_RED : FTDM_ALARM_NONE; - ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Link status is %d\n", sangoma_status); } } From bbe1fe1a31cdb555fbf71b4669e8b6d8b1548ebb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 27 Nov 2013 10:20:29 -0600 Subject: [PATCH 144/656] FS-6005 --resolve --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index bd0253e8c0..f36394da87 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Fri Oct 25 23:51:29 CDT 2013 +Wed Nov 27 10:20:13 CST 2013 diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index 9b862415a3..f0b4d35d58 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -270,8 +270,10 @@ void nua_session_usage_remove(nua_handle_t *nh, ss->ss_reporting = 0; } - if (cr == du->du_cr && cr->cr_orq) + if (cr == du->du_cr && cr->cr_orq) { + nua_client_request_unref(cr); continue; + } if (cr->cr_status < 200) { nua_stack_event(nh->nh_nua, nh, From 3e00d270d7477a63b3c2e845b5473e6e7e3f1cfc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 27 Nov 2013 12:40:35 -0600 Subject: [PATCH 145/656] FS-6006 --resolve --- src/switch_core_session.c | 13 +++++++++++-- src/switch_ivr.c | 3 +++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 0056e2d155..22964a3c72 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -766,6 +766,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit switch_assert(session != NULL); + if (message->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) { + if (session->endpoint_interface->io_routines->receive_message) { + status = session->endpoint_interface->io_routines->receive_message(session, message); + } + + switch_core_session_free_message(&message); + return status; + } + if ((status = switch_core_session_read_lock_hangup(session)) != SWITCH_STATUS_SUCCESS) { return status; } @@ -821,7 +830,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit } - if (switch_channel_down_nosig(session->channel) && message->message_id != SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) { + if (switch_channel_down_nosig(session->channel)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line, switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n", switch_channel_get_name(session->channel), message_names[message->message_id]); @@ -830,7 +839,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit if (session->media_handle) { status = switch_core_media_receive_message(session, message); } - if (status == SWITCH_STATUS_SUCCESS || message->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) { + if (status == SWITCH_STATUS_SUCCESS) { if (session->endpoint_interface->io_routines->receive_message) { status = session->endpoint_interface->io_routines->receive_message(session, message); } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 1f91ed9625..daba288c7e 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -811,6 +811,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_ses int i = 0; switch_channel_t *channel = switch_core_session_get_channel(session); + if (!switch_core_session_in_thread(session)) { + return SWITCH_STATUS_FALSE; + } if (switch_channel_test_flag(channel, CF_SIGNAL_DATA)) { return SWITCH_STATUS_FALSE; From a19d013d3e27d426fbd6166f3478fdd65dc4b8fb Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Wed, 27 Nov 2013 19:19:31 -0500 Subject: [PATCH 146/656] FS-5993 --resolve --- src/mod/applications/mod_callcenter/mod_callcenter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 3286cea05a..cd8ed15dbc 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1584,7 +1584,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa if (atoi(res) == 0) { goto done; } - switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", h->member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL); + switch_core_session_hupall_matching_var("cc_member_pre_answer_uuid", h->member_uuid, SWITCH_CAUSE_LOSE_RACE); } t_agent_answered = local_epoch_time_now(NULL); From 30325093d4d7c8c9b0df8e3edb9ea093344b93e5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 27 Nov 2013 23:55:00 -0600 Subject: [PATCH 147/656] FS-6009 --resolve --- src/mod/endpoints/mod_sofia/sofia_presence.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 90f251dfb9..747f4491e5 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3770,13 +3770,13 @@ void sofia_presence_handle_sip_i_subscribe(int status, if (sub_state == nua_substate_active) { sstr = switch_mprintf("active;expires=%ld", exp_delta); - + sql = switch_mprintf("update sip_subscriptions " "set expires=%ld, " - "network_ip='%q',network_port='%d',sip_user='%q',sip_host='%q',full_via='%q',full_to='%q;tag=%q',full_from='%q',contact='%q' " + "network_ip='%q',network_port='%d',sip_user='%q',sip_host='%q',full_via='%q',full_to='%q',full_from='%q',contact='%q' " "where call_id='%q' and profile_name='%q' and hostname='%q'", (long) switch_epoch_time_now(NULL) + exp_delta, - np.network_ip, np.network_port, from_user, from_host, full_via, full_to, use_to_tag, full_from, contact_str, + np.network_ip, np.network_port, from_user, from_host, full_via, full_to, full_from, contact_str, call_id, profile->name, mod_sofia_globals.hostname); From 9ecbb5406104ca710ee28009415aa5339de40198 Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Thu, 28 Nov 2013 01:28:00 -0500 Subject: [PATCH 148/656] FS-5850 --resolve Thanks --- .../mod_callcenter/mod_callcenter.c | 134 ++++++++++++++---- 1 file changed, 106 insertions(+), 28 deletions(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index cd8ed15dbc..785d44bc5e 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -1249,13 +1249,74 @@ end: return SWITCH_STATUS_SUCCESS; } +static switch_status_t load_tier(const char *queue, const char *agent, const char *level, const char *position) +{ + /* Hack to check if an tier already exist */ + if (cc_tier_update("unknown", "unknown", queue, agent) == CC_STATUS_TIER_NOT_FOUND) { + if (level && position) { + cc_tier_add(queue, agent, cc_tier_state2str(CC_TIER_STATE_READY), atoi(level), atoi(position)); + } else { + /* default to level 1 and position 1 within the level */ + cc_tier_add(queue, agent, cc_tier_state2str(CC_TIER_STATE_READY), 0, 0); + } + } else { + if (level) { + cc_tier_update("level", level, queue, agent); + } + if (position) { + cc_tier_update("position", position, queue, agent); + } + } + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t load_tiers(switch_bool_t load_all, const char *queue_name, const char *agent_name) +{ + switch_xml_t x_tiers, x_tier, cfg, xml; + switch_status_t result = SWITCH_STATUS_FALSE; + + if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); + return SWITCH_STATUS_FALSE; + } + + if (!(x_tiers = switch_xml_child(cfg, "tiers"))) { + goto end; + } + + /* Importing from XML config Agent Tiers */ + for (x_tier = switch_xml_child(x_tiers, "tier"); x_tier; x_tier = x_tier->next) { + const char *agent = switch_xml_attr(x_tier, "agent"); + const char *queue = switch_xml_attr(x_tier, "queue"); + const char *level = switch_xml_attr(x_tier, "level"); + const char *position = switch_xml_attr(x_tier, "position"); + if (load_all == SWITCH_TRUE) { + result = load_tier(queue, agent, level, position); + } else if (!zstr(agent_name) && !zstr(queue_name) && !strcasecmp(agent, agent_name) && !strcasecmp(queue, queue_name)) { + result = load_tier(queue, agent, level, position); + } else if (zstr(agent_name) && !strcasecmp(queue, queue_name)) { + result = load_tier(queue, agent, level, position); + } else if (zstr(queue_name) && !strcasecmp(agent, agent_name)) { + result = load_tier(queue, agent, level, position); + } + } + +end: + + if (xml) { + switch_xml_free(xml); + } + + return result; +} + static switch_status_t load_config(void) { switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_xml_t cfg, xml, settings, param, x_queues, x_queue, x_agents, x_agent, x_tiers, x_tier; + switch_xml_t cfg, xml, settings, param, x_queues, x_queue, x_agents, x_agent; switch_cache_db_handle_t *dbh = NULL; char *sql = NULL; - + if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); status = SWITCH_STATUS_TERM; @@ -1323,32 +1384,7 @@ static switch_status_t load_config(void) } /* Importing from XML config Agent Tiers */ - if ((x_tiers = switch_xml_child(cfg, "tiers"))) { - for (x_tier = switch_xml_child(x_tiers, "tier"); x_tier; x_tier = x_tier->next) { - const char *agent = switch_xml_attr(x_tier, "agent"); - const char *queue_name = switch_xml_attr(x_tier, "queue"); - const char *level = switch_xml_attr(x_tier, "level"); - const char *position = switch_xml_attr(x_tier, "position"); - if (agent && queue_name) { - /* Hack to check if an tier already exist */ - if (cc_tier_update("unknown", "unknown", queue_name, agent) == CC_STATUS_TIER_NOT_FOUND) { - if (level && position) { - cc_tier_add(queue_name, agent, cc_tier_state2str(CC_TIER_STATE_READY), atoi(level), atoi(position)); - } else { - /* default to level 1 and position 1 within the level */ - cc_tier_add(queue_name, agent, cc_tier_state2str(CC_TIER_STATE_READY), 0, 0); - } - } else { - if (level) { - cc_tier_update("level", level, queue_name, agent); - } - if (position) { - cc_tier_update("position", position, queue_name, agent); - } - } - } - } - } + load_tiers(SWITCH_TRUE, NULL, NULL); end: switch_mutex_unlock(globals.mutex); @@ -2736,6 +2772,7 @@ static int list_result_callback(void *pArg, int argc, char **argv, char **column #define CC_CONFIG_API_SYNTAX "callcenter_config ,\n"\ "\tcallcenter_config agent add [name] [type] | \n" \ "\tcallcenter_config agent del [name] | \n" \ +"\tcallcenter_config agent reload [name] | \n" \ "\tcallcenter_config agent set status [agent_name] [status] | \n" \ "\tcallcenter_config agent set state [agent_name] [state] | \n" \ "\tcallcenter_config agent set contact [agent_name] [contact] | \n" \ @@ -2752,6 +2789,7 @@ static int list_result_callback(void *pArg, int argc, char **argv, char **column "\tcallcenter_config tier set level [queue_name] [agent_name] [level] | \n" \ "\tcallcenter_config tier set position [queue_name] [agent_name] [position] | \n" \ "\tcallcenter_config tier del [queue_name] [agent_name] | \n" \ +"\tcallcenter_config tier reload [queue_name] [agent_name] | \n" \ "\tcallcenter_config tier list | \n" \ "\tcallcenter_config queue load [queue_name] | \n" \ "\tcallcenter_config queue unload [queue_name] | \n" \ @@ -2837,6 +2875,22 @@ SWITCH_STANDARD_API(cc_config_api_function) } } + } else if (action && !strcasecmp(action, "reload")) { + if (argc-initial_argc < 1) { + stream->write_function(stream, "%s", "-ERR Invalid!\n"); + goto done; + } else { + const char *agent = argv[0 + initial_argc]; + switch (load_agent(agent)) { + case SWITCH_STATUS_SUCCESS: + stream->write_function(stream, "%s", "+OK\n"); + break; + default: + stream->write_function(stream, "%s", "-ERR Unknown Error!\n"); + goto done; + } + } + } else if (action && !strcasecmp(action, "set")) { if (argc-initial_argc < 3) { stream->write_function(stream, "%s", "-ERR Invalid!\n"); @@ -3002,6 +3056,28 @@ SWITCH_STANDARD_API(cc_config_api_function) } } + } else if (action && !strcasecmp(action, "reload")) { + if (argc-initial_argc < 1) { + stream->write_function(stream, "%s", "-ERR Invalid!\n"); + goto done; + } else { + const char *queue = argv[0 + initial_argc]; + const char *agent = argv[1 + initial_argc]; + switch_bool_t load_all = SWITCH_FALSE; + if (!strcasecmp(queue, "all")) { + load_all = SWITCH_TRUE; + } + switch (load_tiers(load_all, queue, agent)) { + case SWITCH_STATUS_SUCCESS: + stream->write_function(stream, "%s", "+OK\n"); + break; + default: + stream->write_function(stream, "%s", "-ERR Unknown Error!\n"); + goto done; + + } + } + } else if (action && !strcasecmp(action, "list")) { struct list_result cbt; cbt.row_process = 0; @@ -3194,6 +3270,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load) switch_console_set_complete("add callcenter_config agent add"); switch_console_set_complete("add callcenter_config agent del"); + switch_console_set_complete("add callcenter_config agent reload"); switch_console_set_complete("add callcenter_config agent set status"); switch_console_set_complete("add callcenter_config agent set state"); switch_console_set_complete("add callcenter_config agent set uuid"); @@ -3207,6 +3284,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load) switch_console_set_complete("add callcenter_config tier add"); switch_console_set_complete("add callcenter_config tier del"); + switch_console_set_complete("add callcenter_config tier reload"); switch_console_set_complete("add callcenter_config tier set state"); switch_console_set_complete("add callcenter_config tier set level"); switch_console_set_complete("add callcenter_config tier set position"); From bb53175526fd8270276f4901f2edcc4995cfbbb4 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 29 Nov 2013 22:16:49 -0600 Subject: [PATCH 149/656] FS-6010 --resolve --- libs/apr/atomic/win32/apr_atomic.c | 18 ++++++++++++++++++ libs/esl/src/esl_event.c | 2 +- libs/ilbc/src/iLBC_decode.c | 2 ++ libs/libsndfile/src/float_cast.h | 2 ++ libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c | 2 ++ libs/sofia-sip/libsofia-sip-ua/su/strtoull.c | 7 ++++++- libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c | 2 ++ libs/spandsp/src/msvc/config.h | 2 ++ libs/spandsp/src/spandsp/fast_convert.h | 4 ++++ src/switch_time.c | 2 +- 10 files changed, 40 insertions(+), 3 deletions(-) diff --git a/libs/apr/atomic/win32/apr_atomic.c b/libs/apr/atomic/win32/apr_atomic.c index 9393fcb008..18a7bcd0ba 100644 --- a/libs/apr/atomic/win32/apr_atomic.c +++ b/libs/apr/atomic/win32/apr_atomic.c @@ -27,6 +27,7 @@ APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p) * Remapping function pointer type to accept apr_uint32_t's type-safely * as the arguments for as our apr_atomic_foo32 Functions */ +#if (_MSC_VER < 1800) typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_fn) (apr_uint32_t volatile *); typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_fn) @@ -38,11 +39,14 @@ typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_val_fn) typedef WINBASEAPI void * (WINAPI * apr_atomic_win32_ptr_ptr_ptr_fn) (volatile void **, void *, const void *); +#endif APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val) { #if (defined(_M_IA64) || defined(_M_AMD64)) return InterlockedExchangeAdd(mem, val); +#elif (_MSC_VER >= 1800) + return InterlockedExchangeAdd(mem, val); #else return ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, val); #endif @@ -55,6 +59,8 @@ APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val) { #if (defined(_M_IA64) || defined(_M_AMD64)) InterlockedExchangeAdd(mem, -val); +#elif (_MSC_VER >= 1800) + InterlockedExchangeAdd(mem, -val); #else ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, -val); #endif @@ -65,6 +71,8 @@ APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem) /* we return old value, win32 returns new value :( */ #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) return InterlockedIncrement(mem) - 1; +#elif (_MSC_VER >= 1800) + return InterlockedIncrement(mem) - 1; #else return ((apr_atomic_win32_ptr_fn)InterlockedIncrement)(mem) - 1; #endif @@ -74,6 +82,8 @@ APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem) { #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) return InterlockedDecrement(mem); +#elif (_MSC_VER >= 1800) + return InterlockedDecrement(mem); #else return ((apr_atomic_win32_ptr_fn)InterlockedDecrement)(mem); #endif @@ -83,6 +93,8 @@ APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val) { #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) InterlockedExchange(mem, val); +#elif (_MSC_VER >= 1800) + InterlockedExchange(mem, val); #else ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem, val); #endif @@ -98,6 +110,8 @@ APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint3 { #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) return InterlockedCompareExchange(mem, with, cmp); +#elif (_MSC_VER >= 1800) + return InterlockedCompareExchange(mem, with, cmp); #else return ((apr_atomic_win32_ptr_val_val_fn)InterlockedCompareExchange)(mem, with, cmp); #endif @@ -107,6 +121,8 @@ APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const voi { #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) return InterlockedCompareExchangePointer(mem, with, cmp); +#elif (_MSC_VER >= 1800) + return InterlockedCompareExchangePointer(mem, with, cmp); #else /* Too many VC6 users have stale win32 API files, stub this */ return ((apr_atomic_win32_ptr_ptr_ptr_fn)InterlockedCompareExchange)(mem, with, cmp); @@ -117,6 +133,8 @@ APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint { #if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) return InterlockedExchange(mem, val); +#elif (_MSC_VER >= 1800) + return InterlockedExchange(mem, val); #else return ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem, val); #endif diff --git a/libs/esl/src/esl_event.c b/libs/esl/src/esl_event.c index b5a6be4d58..41f4f9f0ac 100644 --- a/libs/esl/src/esl_event.c +++ b/libs/esl/src/esl_event.c @@ -308,7 +308,7 @@ ESL_DECLARE(esl_status_t) esl_event_del_header_val(esl_event_t *event, const cha esl_assert(x < 1000000); hash = esl_ci_hashfunc_default(header_name, &hlen); - if ((!hp->hash || hash == hp->hash) && (hp->name && !strcasecmp(header_name, hp->name)) && (esl_strlen_zero(val) || !strcmp(hp->value, val))) { + if ((!hp->hash || hash == hp->hash) && (hp->name && !strcasecmp(header_name, hp->name)) && (esl_strlen_zero(val) || (hp->value && !strcmp(hp->value, val)))) { if (lp) { lp->next = hp->next; } else { diff --git a/libs/ilbc/src/iLBC_decode.c b/libs/ilbc/src/iLBC_decode.c index 9fc7a24bb4..ddc164bed8 100644 --- a/libs/ilbc/src/iLBC_decode.c +++ b/libs/ilbc/src/iLBC_decode.c @@ -40,6 +40,7 @@ #include "hpOutput.h" #include "syntFilter.h" +#if (defined(WIN32) || defined(_WIN32)) && (_MSC_VER < 1800) #if (defined(WIN32) || defined(_WIN32)) && !defined(_WIN64) __inline long int rint(double dbl) { @@ -63,6 +64,7 @@ #endif } #endif +#endif /*----------------------------------------------------------------* * Initiation of decoder instance. diff --git a/libs/libsndfile/src/float_cast.h b/libs/libsndfile/src/float_cast.h index 2c06aaf233..98c7de74b1 100644 --- a/libs/libsndfile/src/float_cast.h +++ b/libs/libsndfile/src/float_cast.h @@ -158,6 +158,7 @@ } #elif defined(_WIN64) +#if (_MSC_VER < 1800) __inline long int lrint(double x) { return (long int) (x); @@ -166,6 +167,7 @@ { return (long int) (x); } +#endif #elif (defined (__MWERKS__) && defined (macintosh)) /* This MacOS 9 solution was provided by Stephane Letz */ diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c index 7877100978..f29d7139bb 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c @@ -1808,8 +1808,10 @@ static int parse_ul(sdp_parser_t *p, char **r, } #if !HAVE_STRTOULL +#if !((defined(WIN32) || defined(_WIN32)) && (_MSC_VER >= 1800)) unsigned long long strtoull(char const *string, char **return_end, int base); #endif +#endif /* * parse_ull: parse an unsigned long long diff --git a/libs/sofia-sip/libsofia-sip-ua/su/strtoull.c b/libs/sofia-sip/libsofia-sip-ua/su/strtoull.c index c4854aaeac..824a39df43 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/strtoull.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/strtoull.c @@ -73,7 +73,10 @@ static char cvtIn[] = { 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35}; - + + +#if !((defined(WIN32) || defined(_WIN32)) && (_MSC_VER >= 1800)) + /**Convert an ASCII string into an unsigned long long integer. * * @param[in] string String of ASCII digits, possibly preceded by white @@ -284,3 +287,5 @@ strtoull(const char *string, char **endPtr, int base) return (unsigned longlong)-1; } + +#endif diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c b/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c index 65037c2d18..431a2dcb56 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su_taglist.c @@ -60,8 +60,10 @@ #include #ifndef HAVE_STRTOULL +#if !((defined(WIN32) || defined(_WIN32)) && (_MSC_VER >= 1800)) unsigned longlong strtoull(const char *, char **, int); #endif +#endif /**@defgroup su_tag Tag Item Lists * diff --git a/libs/spandsp/src/msvc/config.h b/libs/spandsp/src/msvc/config.h index 876f66f56a..c974d7c7c4 100644 --- a/libs/spandsp/src/msvc/config.h +++ b/libs/spandsp/src/msvc/config.h @@ -74,7 +74,9 @@ #define _MMX_H_ + #if !((defined(WIN32) || defined(_WIN32)) && (_MSC_VER >= 1800)) #define cbrtf(value) pow((float)value, (float).333) + #endif #include // To get alloca diff --git a/libs/spandsp/src/spandsp/fast_convert.h b/libs/spandsp/src/spandsp/fast_convert.h index e6da451f9c..120050646f 100644 --- a/libs/spandsp/src/spandsp/fast_convert.h +++ b/libs/spandsp/src/spandsp/fast_convert.h @@ -247,6 +247,7 @@ extern "C" * Therefore implement inline versions of these functions here. */ +#if (_MSC_VER < 1800) __inline long int lrint(double x) { long int i; @@ -288,6 +289,7 @@ extern "C" frndint } } +#endif __inline long int lfastrint(double x) { @@ -317,6 +319,7 @@ extern "C" /* x86_64 machines will do best with a simple assignment. */ #include +#if (_MSC_VER < 1800) __inline long int lrint(double x) { return (long int)_mm_cvtsd_si64x( _mm_loadu_pd ((const double*)&x) ); @@ -326,6 +329,7 @@ extern "C" { return _mm_cvt_ss2si( _mm_load_ss((const float*)&x) ); } +#endif __inline long int lfastrint(double x) { diff --git a/src/switch_time.c b/src/switch_time.c index c4b6b8b445..63152aac31 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -756,7 +756,7 @@ static switch_status_t timer_step(switch_timer_t *timer) } check_roll(); - samples = timer->samples * (private_info->reference - private_info->start); + samples = (uint64_t)timer->samples * (private_info->reference - private_info->start); if (samples > UINT32_MAX) { private_info->start = private_info->reference - 1; /* Must have a diff */ From 4e6852fd88f40332c3c9bdb3e5958f2c85a02b2c Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 29 Nov 2013 22:23:08 -0600 Subject: [PATCH 150/656] FS-5989 --resolve --- src/mod/applications/mod_avmd/mod_avmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 15f954b326..68c72755fc 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -539,7 +539,7 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame) /*! If variance is less than threshold then we have detection */ if(v < VARIANCE_THRESHOLD){ - switch_channel_execute_on(switch_core_session_get_channel(session), "execute_on_avmd_beep"); + switch_channel_execute_on(switch_core_session_get_channel(session->session), "execute_on_avmd_beep"); /*! Throw an event to FreeSWITCH */ status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP); From ae99177598736a21fda7b48018ce9ed9748ae8c4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 30 Nov 2013 19:13:49 -0600 Subject: [PATCH 151/656] add more range to saved candidates and fix off-by-one error when total is met --- src/include/switch_rtp.h | 2 +- src/switch_core_media.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index ca0b3f3b8d..82dde7a798 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -96,7 +96,7 @@ typedef struct icand_s { uint8_t ready; } icand_t; -#define MAX_CAND 25 +#define MAX_CAND 50 typedef struct ice_s { icand_t cands[MAX_CAND][2]; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index a8336dd03b..8008e0ccee 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2332,6 +2332,8 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ data = switch_core_session_strdup(smh->session, attr->a_value); argc = switch_split(data, ' ', fields); + + engine->ice_in.cand_idx++; if (argc < 5 || engine->ice_in.cand_idx >= MAX_CAND) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n"); @@ -2349,8 +2351,6 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ "Checking Candidate cid: %d proto: %s type: %s addr: %s:%s\n", cid+1, fields[2], fields[7], fields[4], fields[5]); - engine->ice_in.cand_idx++; - for (i = 0; i < engine->cand_acl_count; i++) { if (!engine->ice_in.chosen[cid] && switch_check_network_list_ip(fields[4], engine->cand_acl[i])) { engine->ice_in.chosen[cid] = engine->ice_in.cand_idx; From d050d9ef3caf0d086d36c56add4c571709e62ff7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 30 Nov 2013 19:26:12 -0600 Subject: [PATCH 152/656] FS-6012 --resolve --- src/mod/applications/mod_spandsp/udptl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_spandsp/udptl.c b/src/mod/applications/mod_spandsp/udptl.c index 45fa6b6ffc..553e4135e3 100644 --- a/src/mod/applications/mod_spandsp/udptl.c +++ b/src/mod/applications/mod_spandsp/udptl.c @@ -170,8 +170,8 @@ int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len) int count; int total_count; int seq_no; - const uint8_t *msg; - const uint8_t *data; + const uint8_t *msg = NULL; + const uint8_t *data = NULL; int msg_len; int repaired[16]; const uint8_t *bufs[16] = {0}; From 2f7ed973ed98a2ba3ce3a868da6ea065c470828a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 30 Nov 2013 20:49:59 -0600 Subject: [PATCH 153/656] separate read mutex for each stream type --- src/switch_core_media.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 8008e0ccee..80dcec3cc7 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -140,7 +140,7 @@ typedef struct switch_rtp_engine_s { struct media_helper mh; switch_thread_t *media_thread; - switch_mutex_t *read_mutex; + switch_mutex_t *read_mutex[2]; uint8_t reset_codec; uint8_t codec_negotiated; @@ -1427,7 +1427,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session return SWITCH_STATUS_FALSE; } - if (switch_mutex_trylock(engine->read_mutex) != SWITCH_STATUS_SUCCESS) { + if (engine->read_mutex[type] && switch_mutex_trylock(engine->read_mutex[type]) != SWITCH_STATUS_SUCCESS) { /* return CNG, another thread is already reading */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being read for %s\n", switch_channel_get_name(session->channel), type2str(type)); @@ -1759,7 +1759,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session end: - switch_mutex_unlock(engine->read_mutex); + if (engine->read_mutex[type]) { + switch_mutex_unlock(engine->read_mutex[type]); + } return status; } @@ -3853,7 +3855,7 @@ static switch_status_t start_video_thread(switch_core_session_t *session) switch_thread_cond_create(&v_engine->mh.cond, pool); switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool); - switch_mutex_init(&v_engine->read_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&v_engine->read_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool); switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, switch_core_session_get_pool(session)); return SWITCH_STATUS_SUCCESS; @@ -4665,7 +4667,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi uint8_t inb = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND; const char *ssrc; - switch_mutex_init(&a_engine->read_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); + switch_mutex_init(&a_engine->read_mutex[SWITCH_MEDIA_TYPE_AUDIO], SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); //switch_core_media_set_rtp_session(session, SWITCH_MEDIA_TYPE_AUDIO, a_engine->rtp_session); From a0e2fc0342d91f27e53186966d3f2ce5d885b38e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 30 Nov 2013 21:02:52 -0600 Subject: [PATCH 154/656] swigall --- src/mod/languages/mod_managed/freeswitch_wrap.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 4d4750877c..ea1a306269 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -36574,7 +36574,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_MAX_CAND_get() { int jresult ; int result; - result = (int) 25; + result = (int) 50; jresult = result; return jresult; @@ -36591,7 +36591,7 @@ SWIGEXPORT void SWIGSTDCALL CSharp_ice_t_cands_set(void * jarg1, void * jarg2) { icand_t (*inp)[2] = (icand_t (*)[2])(arg2); icand_t (*dest)[2] = (icand_t (*)[2])(arg1->cands); size_t ii = 0; - for (; ii < 25; ++ii) { + for (; ii < 50; ++ii) { icand_t *ip = inp[ii]; icand_t *dp = dest[ii]; size_t jj = 0; From 2b60308891696bc4089a21dc58264e254067ff5e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 1 Dec 2013 02:53:27 -0600 Subject: [PATCH 155/656] redo --- src/switch_core_media.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 80dcec3cc7..cc960c886d 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2334,10 +2334,8 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ data = switch_core_session_strdup(smh->session, attr->a_value); argc = switch_split(data, ' ', fields); - - engine->ice_in.cand_idx++; - if (argc < 5 || engine->ice_in.cand_idx >= MAX_CAND) { + if (argc < 5 || engine->ice_in.cand_idx >= MAX_CAND - 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n"); continue; } @@ -2353,6 +2351,8 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ "Checking Candidate cid: %d proto: %s type: %s addr: %s:%s\n", cid+1, fields[2], fields[7], fields[4], fields[5]); + engine->ice_in.cand_idx++; + for (i = 0; i < engine->cand_acl_count; i++) { if (!engine->ice_in.chosen[cid] && switch_check_network_list_ip(fields[4], engine->cand_acl[i])) { engine->ice_in.chosen[cid] = engine->ice_in.cand_idx; From e127ca7d4022c10cfa100afb080e14a0aa795111 Mon Sep 17 00:00:00 2001 From: Robert Jongbloed Date: Tue, 3 Dec 2013 09:48:06 +1100 Subject: [PATCH 156/656] Updated to current stable version of PTLib/OPAL. --- src/mod/endpoints/mod_opal/mod_opal.cpp | 2 +- src/mod/endpoints/mod_opal/mod_opal.h | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) mode change 100644 => 100755 src/mod/endpoints/mod_opal/mod_opal.cpp mode change 100644 => 100755 src/mod/endpoints/mod_opal/mod_opal.h diff --git a/src/mod/endpoints/mod_opal/mod_opal.cpp b/src/mod/endpoints/mod_opal/mod_opal.cpp old mode 100644 new mode 100755 index 6f0fb3addd..7d97c29b51 --- a/src/mod/endpoints/mod_opal/mod_opal.cpp +++ b/src/mod/endpoints/mod_opal/mod_opal.cpp @@ -1031,7 +1031,7 @@ switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg { PTRACE(2, "mod_opal\tRequesting switch to T.38"); PSafePtr other = GetOtherPartyConnection(); - if (other != NULL && other->SwitchT38(true)) + if (other != NULL && other->SwitchFaxMediaStreams(true)) switch_channel_set_flag(m_fsChannel, CF_REQ_MEDIA); else { PTRACE(1, "mod_opal\tMode change request to T.38 failed"); diff --git a/src/mod/endpoints/mod_opal/mod_opal.h b/src/mod/endpoints/mod_opal/mod_opal.h old mode 100644 new mode 100755 index 7b3993b0b2..4b0cd62a02 --- a/src/mod/endpoints/mod_opal/mod_opal.h +++ b/src/mod/endpoints/mod_opal/mod_opal.h @@ -32,13 +32,17 @@ #endif #include +#include -#if !defined(PTLIB_CHECK_VERSION) - #error PTLib is too old to use, must be >= 2.10.6 +#ifndef OPAL_CHECK_VERSION + #define OPAL_CHECK_VERSION(a,b,c) 0 #endif -#include -#include +#if !OPAL_CHECK_VERSION(3,12,8) + #error OPAL is too old to use, must be >= 2.12.8 +#endif + +#include #include #include @@ -53,11 +57,8 @@ #define MODNAME "mod_opal" -#ifndef OPAL_CHECK_VERSION - #define OPAL_CHECK_VERSION(a,b,c) 0 -#endif +#define HAVE_T38 OPAL_T38_CAPABILITY -#define HAVE_T38 (OPAL_CHECK_VERSION(3,11,2) && OPAL_T38_CAPABILITY) class FSEndPoint; From 70accd9f272472ac2081283f1927d901b409acb6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 4 Dec 2013 17:46:02 -0600 Subject: [PATCH 157/656] FS-5997 --resolve --- src/switch_ivr_originate.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index a284bfc036..0afad2ba2a 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -130,6 +130,7 @@ typedef struct { typedef enum { + IDX_XFER = -5, IDX_KEY_CANCEL = -4, IDX_TIMEOUT = -3, IDX_CANCEL = -2, @@ -3358,7 +3359,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_channel_set_flag(peer_channel, CF_LAZY_ATTENDED_TRANSFER); switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(peer_session)); holding = NULL; - oglobals.idx = IDX_NADA; + oglobals.idx = IDX_XFER; if (caller_channel && switch_channel_up_nosig(caller_channel) && !switch_channel_test_flag(caller_channel, CF_INTERCEPTED)) { switch_channel_hangup(caller_channel, SWITCH_CAUSE_ATTENDED_TRANSFER); } @@ -3668,8 +3669,15 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } else if (oglobals.idx == IDX_TIMEOUT) { *cause = SWITCH_CAUSE_NO_ANSWER; } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, - "Originate Resulted in Error Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause)); + if (oglobals.idx == IDX_XFER) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, + "Originate Resulted in Attended Transfer Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause)); + goto outer_for; + } else { + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, + "Originate Resulted in Error Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause)); + } } } From 4a2054a9515191784181019aa17409413c4e7ab3 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 4 Dec 2013 20:18:09 -0500 Subject: [PATCH 158/656] mod_rayo: doh- fix adhearsionconf core dump --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 6d95d28885..a6b749a869 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -3936,10 +3936,15 @@ static int presence_api(char *cmd, switch_stream_handle_t *stream) SWITCH_STANDARD_API(rayo_api) { struct rayo_cmd_alias *alias; - char *cmd_dup = strdup(cmd); + char *cmd_dup = NULL; char *argv[2] = { 0 }; int success = 0; + if (zstr(cmd) ) { + goto done; + } + + cmd_dup = strdup(cmd); switch_separate_string(cmd_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); /* check if a command alias */ @@ -3957,11 +3962,12 @@ SWITCH_STANDARD_API(rayo_api) success = presence_api(argv[1], stream); } +done: if (!success) { stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_API_SYNTAX); } - free(cmd_dup); + switch_safe_free(cmd_dup); return SWITCH_STATUS_SUCCESS; } From 7d6b0e48b76c74b519233c30d76264e8ef078f31 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Thu, 5 Dec 2013 13:34:25 +0800 Subject: [PATCH 159/656] Added an XML script to the FAX tests which will provoke the crashing issue seen recently in spandsp's FAX engine. The next step is to fix the actual crash. --- libs/spandsp/spandsp/fax-tests.xml | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/libs/spandsp/spandsp/fax-tests.xml b/libs/spandsp/spandsp/fax-tests.xml index e770e244b8..82a3e1490d 100644 --- a/libs/spandsp/spandsp/fax-tests.xml +++ b/libs/spandsp/spandsp/fax-tests.xml @@ -87,6 +87,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 9edbbd9c61efedc60830f66a0c2d66812886ad6e Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Thu, 5 Dec 2013 21:10:57 +0800 Subject: [PATCH 160/656] Tweaks to FAX modem handling. These do NOT fix the occassional crashes people see, but they are working towards a clean and complete fix. --- libs/spandsp/spandsp/fax-tests.xml | 2 +- libs/spandsp/spandsp/tsb85.xml | 2 +- libs/spandsp/src/fax.c | 8 + libs/spandsp/src/fax_modems.c | 28 +++- libs/spandsp/src/libspandsp.2005.sln | 68 -------- libs/spandsp/src/libspandsp.2008.sln | 209 ------------------------ libs/spandsp/tests/tsb85_extra_tests.sh | 2 +- 7 files changed, 33 insertions(+), 286 deletions(-) delete mode 100644 libs/spandsp/src/libspandsp.2005.sln delete mode 100644 libs/spandsp/src/libspandsp.2008.sln diff --git a/libs/spandsp/spandsp/fax-tests.xml b/libs/spandsp/spandsp/fax-tests.xml index 82a3e1490d..23f333a396 100644 --- a/libs/spandsp/spandsp/fax-tests.xml +++ b/libs/spandsp/spandsp/fax-tests.xml @@ -163,7 +163,7 @@ - + diff --git a/libs/spandsp/spandsp/tsb85.xml b/libs/spandsp/spandsp/tsb85.xml index 8826098946..482e18b989 100644 --- a/libs/spandsp/spandsp/tsb85.xml +++ b/libs/spandsp/spandsp/tsb85.xml @@ -423,7 +423,7 @@ - + diff --git a/libs/spandsp/src/fax.c b/libs/spandsp/src/fax.c index 8d8b3b25bc..ddc45a04d8 100644 --- a/libs/spandsp/src/fax.c +++ b/libs/spandsp/src/fax.c @@ -77,6 +77,10 @@ #include "spandsp/v27ter_rx.h" #include "spandsp/v17tx.h" #include "spandsp/v17rx.h" +#if defined(SPANDSP_SUPPORT_V34) +#include "spandsp/bitstream.h" +#include "spandsp/v34.h" +#endif #include "spandsp/timezone.h" #include "spandsp/t4_rx.h" #include "spandsp/t4_tx.h" @@ -103,6 +107,10 @@ #include "spandsp/private/fsk.h" #include "spandsp/private/modem_connect_tones.h" #include "spandsp/private/v8.h" +#if defined(SPANDSP_SUPPORT_V34) +#include "spandsp/private/bitstream.h" +#include "spandsp/private/v34.h" +#endif #include "spandsp/private/v17tx.h" #include "spandsp/private/v17rx.h" #include "spandsp/private/v27ter_tx.h" diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c index e298f4d70a..14f4db0fe3 100644 --- a/libs/spandsp/src/fax_modems.c +++ b/libs/spandsp/src/fax_modems.c @@ -5,7 +5,7 @@ * * Written by Steve Underwood * - * Copyright (C) 2003, 2005, 2006, 2008 Steve Underwood + * Copyright (C) 2003, 2005, 2006, 2008, 2013 Steve Underwood * * All rights reserved. * @@ -139,6 +139,12 @@ SPAN_DECLARE(const char *) fax_modem_to_str(int modem) return "V.27ter Rx"; case FAX_MODEM_V29_RX: return "V.29 Rx"; +#if defined(SPANDSP_SUPPORT_V34) + case FAX_MODEM_V34_TX: + return "V.34 HDX Tx"; + case FAX_MODEM_V34_RX: + return "V.34 HDX Rx"; +#endif } /*endswitch*/ return "???"; @@ -150,8 +156,8 @@ static void fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, fax_modems_state_t *s; s = (fax_modems_state_t *) user_data; - if (ok) - s->rx_frame_received = false; + if (len >= 0 && ok) + s->rx_frame_received = true; if (s->hdlc_accept) s->hdlc_accept(s->hdlc_accept_user_data, msg, len, ok); } @@ -322,7 +328,7 @@ SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which) fsk_rx_init(&s->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) hdlc_rx_put_bit, &s->hdlc_rx); fax_modems_set_rx_handler(s, (span_rx_handler_t) &fsk_rx, &s->v21_rx, (span_rx_fillin_handler_t) &fsk_rx_fillin, &s->v21_rx); fsk_rx_signal_cutoff(&s->v21_rx, -39.09f); - s->rx_frame_received = false; + //hdlc_rx_init(&s->hdlc_rx, false, true, HDLC_FRAMING_OK_THRESHOLD, fax_modems_hdlc_accept, s); break; case FAX_MODEM_CED_TONE_RX: modem_connect_tones_rx_init(&s->connect_rx, MODEM_CONNECT_TONES_FAX_CED, s->tone_callback, s->tone_callback_user_data); @@ -348,6 +354,8 @@ SPAN_DECLARE(void) fax_modems_start_slow_modem(fax_modems_state_t *s, int which) fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; } + /*endswitch*/ + s->rx_frame_received = false; } /*- End of function --------------------------------------------------------*/ @@ -365,6 +373,7 @@ SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, get_bit_user_data = (void *) &s->hdlc_tx; put_bit = (put_bit_func_t) hdlc_rx_put_bit; put_bit_user_data = (void *) &s->hdlc_rx; + //hdlc_rx_init(&s->hdlc_rx, false, true, HDLC_FRAMING_OK_THRESHOLD, fax_modems_hdlc_accept, s); } else { @@ -382,8 +391,6 @@ SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, s->current_rx_type = which; s->short_train = false; s->fast_modem = which; - if (hdlc_mode) - s->rx_frame_received = false; switch (s->fast_modem) { case FAX_MODEM_V27TER_RX: @@ -417,6 +424,14 @@ SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, fax_modems_set_tx_handler(s, (span_tx_handler_t) &v17_tx, &s->fast_modems.v17_tx); fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; +#if defined(SPANDSP_SUPPORT_V34) + case FAX_MODEM_V34_RX: + v34_init(&s->fast_modems.v34, 2400, s->bit_rate, true, false, NULL, NULL, put_bit, put_bit_user_data); + break; + case FAX_MODEM_V34_TX: + v34_init(&s->fast_modems.v34, 2400, s->bit_rate, true, false, get_bit, get_bit_user_data, NULL, NULL); + break; +#endif } /*endswitch*/ } @@ -465,6 +480,7 @@ SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, /*endswitch*/ } /*endif*/ + s->rx_frame_received = false; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/src/libspandsp.2005.sln b/libs/spandsp/src/libspandsp.2005.sln deleted file mode 100644 index 0aa47bda59..0000000000 --- a/libs/spandsp/src/libspandsp.2005.sln +++ /dev/null @@ -1,68 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_at_dictionary", "msvc\make_at_dictionary.2005.vcproj", "{DEE932AB-5911-4700-9EEB-8C7090A0A330}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_modem_filter", "msvc\make_modem_filter.2005.vcproj", "{329A6FA0-0FCC-4435-A950-E670AEFA9838}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspandsp", "libspandsp.2005.vcproj", "{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}" - ProjectSection(ProjectDependencies) = postProject - {329A6FA0-0FCC-4435-A950-E670AEFA9838} = {329A6FA0-0FCC-4435-A950-E670AEFA9838} - {DEE932AB-5911-4700-9EEB-8C7090A0A330} = {DEE932AB-5911-4700-9EEB-8C7090A0A330} - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014} = {401A40CD-5DB4-4E34-AC68-FA99E9FAC014} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspandsp_sim", "..\spandsp-sim\libspandsp_sim.2005.vcproj", "{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}" - ProjectSection(ProjectDependencies) = postProject - {329A6FA0-0FCC-4435-A950-E670AEFA9838} = {329A6FA0-0FCC-4435-A950-E670AEFA9838} - {DEE932AB-5911-4700-9EEB-8C7090A0A330} = {DEE932AB-5911-4700-9EEB-8C7090A0A330} - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014} = {401A40CD-5DB4-4E34-AC68-FA99E9FAC014} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtiff", "libtiff.2005.vcproj", "{401A40CD-5DB4-4E34-AC68-FA99E9FAC014}" - ProjectSection(ProjectDependencies) = postProject - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917} = {2B8A45C9-FEB4-4734-AB37-8DB9DB899917} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download TIFF", "msvc\Download_TIFF.2005.vcproj", "{2B8A45C9-FEB4-4734-AB37-8DB9DB899917}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - All|Win32 = All|Win32 - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.All|Win32.ActiveCfg = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.All|Win32.Build.0 = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Debug|Win32.ActiveCfg = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Debug|Win32.Build.0 = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Release|Win32.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.All|Win32.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.All|Win32.Build.0 = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Debug|Win32.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Debug|Win32.Build.0 = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Release|Win32.ActiveCfg = All|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.All|Win32.ActiveCfg = Release|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.All|Win32.Build.0 = Release|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Debug|Win32.ActiveCfg = Debug|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Debug|Win32.Build.0 = Debug|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Release|Win32.ActiveCfg = Release|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Release|Win32.Build.0 = Release|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.All|Win32.ActiveCfg = Release|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.All|Win32.Build.0 = Release|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Debug|Win32.ActiveCfg = Debug|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Debug|Win32.Build.0 = Debug|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Release|Win32.ActiveCfg = Release|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Release|Win32.Build.0 = Release|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.All|Win32.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.All|Win32.Build.0 = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Debug|Win32.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Debug|Win32.Build.0 = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Release|Win32.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Release|Win32.Build.0 = All|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/libs/spandsp/src/libspandsp.2008.sln b/libs/spandsp/src/libspandsp.2008.sln deleted file mode 100644 index 7a0323998b..0000000000 --- a/libs/spandsp/src/libspandsp.2008.sln +++ /dev/null @@ -1,209 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_at_dictionary", "msvc\make_at_dictionary.2008.vcproj", "{DEE932AB-5911-4700-9EEB-8C7090A0A330}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_modem_filter", "msvc\make_modem_filter.2008.vcproj", "{329A6FA0-0FCC-4435-A950-E670AEFA9838}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspandsp", "libspandsp.2008.vcproj", "{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}" - ProjectSection(ProjectDependencies) = postProject - {329A6FA0-0FCC-4435-A950-E670AEFA9838} = {329A6FA0-0FCC-4435-A950-E670AEFA9838} - {DEE932AB-5911-4700-9EEB-8C7090A0A330} = {DEE932AB-5911-4700-9EEB-8C7090A0A330} - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014} = {401A40CD-5DB4-4E34-AC68-FA99E9FAC014} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_line_models", "..\spandsp-sim\msvc\make_line_models.2008.vcproj", "{F290BADE-82DE-4037-B49D-D563E43169DA}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libspandsp_sim", "..\spandsp-sim\libspandsp_sim.2008.vcproj", "{502F1E51-F0A0-4607-AB7F-05BAB530AAE1}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtiff", "libtiff.2008.vcproj", "{401A40CD-5DB4-4E34-AC68-FA99E9FAC014}" - ProjectSection(ProjectDependencies) = postProject - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917} = {2B8A45C9-FEB4-4734-AB37-8DB9DB899917} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download TIFF", "msvc\Download_TIFF.2008.vcproj", "{2B8A45C9-FEB4-4734-AB37-8DB9DB899917}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t38_core_tests", "..\tests\msvc\t38_core_tests.vcproj", "{A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "t38_non_ecm_buffer_tests", "..\tests\msvc\t38_non_ecm_buffer_tests.vcproj", "{80A3D9D9-3846-4DA5-8676-F940D725EA62}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector_int_tests", "..\tests\msvc\vector_int_tests.vcproj", "{80A60464-29E8-4EE8-BAFA-8708B7C08CC3}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector_float_tests", "..\tests\msvc\vector_float_tests.vcproj", "{EA745FF7-9E4B-4C13-BA19-2EE8165A6245}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "complex_tests", "..\tests\msvc\complex_tests.vcproj", "{A349379F-0FEA-49C8-9535-05F39663337B}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "complex_vector_float_tests", "..\tests\msvc\complex_vector_float_tests.vcproj", "{2B0D705C-1CF2-401C-BFBC-A43FB806908C}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "complex_vector_int_tests", "..\tests\msvc\complex_vector_int_tests.vcproj", "{C2E8B4D1-A398-4D57-94F8-B61F20C7D514}" - ProjectSection(ProjectDependencies) = postProject - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - All|Win32 = All|Win32 - All|x64 = All|x64 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.All|Win32.ActiveCfg = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.All|Win32.Build.0 = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.All|x64.ActiveCfg = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Debug|Win32.ActiveCfg = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Debug|Win32.Build.0 = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Debug|x64.ActiveCfg = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Release|Win32.ActiveCfg = All|Win32 - {DEE932AB-5911-4700-9EEB-8C7090A0A330}.Release|x64.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.All|Win32.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.All|Win32.Build.0 = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.All|x64.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Debug|Win32.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Debug|Win32.Build.0 = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Debug|x64.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Release|Win32.ActiveCfg = All|Win32 - {329A6FA0-0FCC-4435-A950-E670AEFA9838}.Release|x64.ActiveCfg = All|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.All|Win32.ActiveCfg = Release|x64 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.All|x64.ActiveCfg = Release|x64 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.All|x64.Build.0 = Release|x64 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Debug|Win32.ActiveCfg = Debug|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Debug|Win32.Build.0 = Debug|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Debug|x64.ActiveCfg = Debug|x64 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Debug|x64.Build.0 = Debug|x64 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Release|Win32.ActiveCfg = Release|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Release|Win32.Build.0 = Release|Win32 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Release|x64.ActiveCfg = Release|x64 - {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}.Release|x64.Build.0 = Release|x64 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.All|Win32.ActiveCfg = Release|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.All|Win32.Build.0 = Release|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.All|x64.ActiveCfg = Release|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.Debug|Win32.ActiveCfg = Debug|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.Debug|Win32.Build.0 = Debug|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.Debug|x64.ActiveCfg = Debug|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.Release|Win32.ActiveCfg = Release|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.Release|Win32.Build.0 = Release|Win32 - {502F1E51-F0A0-4607-AB7F-05BAB530AAE1}.Release|x64.ActiveCfg = Release|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.All|Win32.ActiveCfg = Release|x64 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.All|x64.ActiveCfg = Release|x64 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.All|x64.Build.0 = Release|x64 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Debug|Win32.ActiveCfg = Debug|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Debug|Win32.Build.0 = Debug|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Debug|x64.ActiveCfg = Debug|x64 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Debug|x64.Build.0 = Debug|x64 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Release|Win32.ActiveCfg = Release|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Release|Win32.Build.0 = Release|Win32 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Release|x64.ActiveCfg = Release|x64 - {401A40CD-5DB4-4E34-AC68-FA99E9FAC014}.Release|x64.Build.0 = Release|x64 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.All|Win32.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.All|Win32.Build.0 = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.All|x64.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Debug|Win32.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Debug|Win32.Build.0 = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Debug|x64.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Release|Win32.ActiveCfg = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Release|Win32.Build.0 = All|Win32 - {2B8A45C9-FEB4-4734-AB37-8DB9DB899917}.Release|x64.ActiveCfg = All|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.All|Win32.ActiveCfg = Release|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.All|Win32.Build.0 = Release|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.All|x64.ActiveCfg = Release|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.Debug|Win32.ActiveCfg = Debug|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.Debug|Win32.Build.0 = Debug|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.Debug|x64.ActiveCfg = Debug|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.Release|Win32.ActiveCfg = Release|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.Release|Win32.Build.0 = Release|Win32 - {A34A9D0E-A7E2-4A04-B044-7BB2FE709EF3}.Release|x64.ActiveCfg = Release|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.All|Win32.ActiveCfg = Release|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.All|Win32.Build.0 = Release|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.All|x64.ActiveCfg = Release|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.Debug|Win32.ActiveCfg = Debug|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.Debug|Win32.Build.0 = Debug|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.Debug|x64.ActiveCfg = Debug|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.Release|Win32.ActiveCfg = Release|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.Release|Win32.Build.0 = Release|Win32 - {80A3D9D9-3846-4DA5-8676-F940D725EA62}.Release|x64.ActiveCfg = Release|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.All|Win32.ActiveCfg = Release|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.All|Win32.Build.0 = Release|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.All|x64.ActiveCfg = Release|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.Debug|Win32.ActiveCfg = Debug|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.Debug|Win32.Build.0 = Debug|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.Debug|x64.ActiveCfg = Debug|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.Release|Win32.ActiveCfg = Release|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.Release|Win32.Build.0 = Release|Win32 - {80A60464-29E8-4EE8-BAFA-8708B7C08CC3}.Release|x64.ActiveCfg = Release|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.All|Win32.ActiveCfg = Release|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.All|Win32.Build.0 = Release|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.All|x64.ActiveCfg = Release|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.Debug|Win32.ActiveCfg = Debug|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.Debug|Win32.Build.0 = Debug|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.Debug|x64.ActiveCfg = Debug|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.Release|Win32.ActiveCfg = Release|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.Release|Win32.Build.0 = Release|Win32 - {EA745FF7-9E4B-4C13-BA19-2EE8165A6245}.Release|x64.ActiveCfg = Release|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.All|Win32.ActiveCfg = Release|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.All|Win32.Build.0 = Release|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.All|x64.ActiveCfg = Release|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.Debug|Win32.ActiveCfg = Debug|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.Debug|Win32.Build.0 = Debug|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.Debug|x64.ActiveCfg = Debug|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.Release|Win32.ActiveCfg = Release|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.Release|Win32.Build.0 = Release|Win32 - {A349379F-0FEA-49C8-9535-05F39663337B}.Release|x64.ActiveCfg = Release|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.All|Win32.ActiveCfg = Release|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.All|Win32.Build.0 = Release|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.All|x64.ActiveCfg = Release|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.Debug|Win32.ActiveCfg = Debug|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.Debug|Win32.Build.0 = Debug|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.Debug|x64.ActiveCfg = Debug|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.Release|Win32.ActiveCfg = Release|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.Release|Win32.Build.0 = Release|Win32 - {2B0D705C-1CF2-401C-BFBC-A43FB806908C}.Release|x64.ActiveCfg = Release|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.All|Win32.ActiveCfg = Release|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.All|Win32.Build.0 = Release|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.All|x64.ActiveCfg = Release|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.Debug|Win32.ActiveCfg = Debug|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.Debug|Win32.Build.0 = Debug|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.Debug|x64.ActiveCfg = Debug|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.Release|Win32.ActiveCfg = Release|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.Release|Win32.Build.0 = Release|Win32 - {C2E8B4D1-A398-4D57-94F8-B61F20C7D514}.Release|x64.ActiveCfg = Release|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.All|Win32.ActiveCfg = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.All|Win32.Build.0 = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.All|x64.ActiveCfg = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.Debug|Win32.ActiveCfg = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.Debug|Win32.Build.0 = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.Debug|x64.ActiveCfg = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.Release|Win32.ActiveCfg = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.Release|Win32.Build.0 = All|Win32 - {F290BADE-82DE-4037-B49D-D563E43169DA}.Release|x64.ActiveCfg = All|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/libs/spandsp/tests/tsb85_extra_tests.sh b/libs/spandsp/tests/tsb85_extra_tests.sh index 2d64fb05b4..8aa3b24740 100755 --- a/libs/spandsp/tests/tsb85_extra_tests.sh +++ b/libs/spandsp/tests/tsb85_extra_tests.sh @@ -28,7 +28,7 @@ run_tsb85_test() fi } -for TEST in PPS-MPS-lost-PPS +for TEST in PPS-MPS-lost-PPS V17-12000-V29-9600 do run_tsb85_test done From d5a7495a72cd6746a33870f6dbad2d3da634dc8c Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Thu, 5 Dec 2013 21:49:59 +0800 Subject: [PATCH 161/656] This should fix the FAX crashes when negotiation falls back to slower modems --- libs/spandsp/src/fax.c | 3 +-- libs/spandsp/src/fax_modems.c | 19 ++++++++++++++++++- libs/spandsp/src/spandsp/fax_modems.h | 2 ++ libs/spandsp/src/t38_gateway.c | 8 ++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/libs/spandsp/src/fax.c b/libs/spandsp/src/fax.c index ddc45a04d8..196c9ab0d3 100644 --- a/libs/spandsp/src/fax.c +++ b/libs/spandsp/src/fax.c @@ -256,8 +256,7 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t return; t->current_rx_type = type; t->rx_bit_rate = bit_rate; - if (use_hdlc) - hdlc_rx_init(&t->hdlc_rx, false, true, HDLC_FRAMING_OK_THRESHOLD, t30_hdlc_accept, &s->t30); + hdlc_rx_init(&t->hdlc_rx, false, true, HDLC_FRAMING_OK_THRESHOLD, fax_modems_hdlc_accept, t); switch (type) { diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c index 14f4db0fe3..74d71ecc29 100644 --- a/libs/spandsp/src/fax_modems.c +++ b/libs/spandsp/src/fax_modems.c @@ -151,7 +151,8 @@ SPAN_DECLARE(const char *) fax_modem_to_str(int modem) } /*- End of function --------------------------------------------------------*/ -static void fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) +//static void fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) +SPAN_DECLARE(void) fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok) { fax_modems_state_t *s; @@ -427,9 +428,13 @@ SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, #if defined(SPANDSP_SUPPORT_V34) case FAX_MODEM_V34_RX: v34_init(&s->fast_modems.v34, 2400, s->bit_rate, true, false, NULL, NULL, put_bit, put_bit_user_data); + //fax_modems_set_tx_handler(s, (span_tx_handler_t) &v34_rx, &s->fast_modems.v34_rx); + fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; case FAX_MODEM_V34_TX: v34_init(&s->fast_modems.v34, 2400, s->bit_rate, true, false, get_bit, get_bit_user_data, NULL, NULL); + //fax_modems_set_tx_handler(s, (span_tx_handler_t) &v34_tx, &s->fast_modems.v34_tx); + fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; #endif } @@ -476,6 +481,18 @@ SPAN_DECLARE(void) fax_modems_start_fast_modem(fax_modems_state_t *s, int which, fax_modems_set_tx_handler(s, (span_tx_handler_t) &v17_tx, &s->fast_modems.v17_tx); fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); break; +#if defined(SPANDSP_SUPPORT_V34) + case FAX_MODEM_V34_RX: + v34_restart(&s->fast_modems.v34, 2400, s->bit_rate, false); + //fax_modems_set_tx_handler(s, (span_tx_handler_t) &v34_rx, &s->fast_modems.v34_rx); + fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); + break; + case FAX_MODEM_V34_TX: + v34_restart(&s->fast_modems.v34, 2400, s->bit_rate, false); + //fax_modems_set_tx_handler(s, (span_tx_handler_t) &v34_tx, &s->fast_modems.v34_tx); + fax_modems_set_next_tx_handler(s, (span_tx_handler_t) NULL, NULL); + break; +#endif } /*endswitch*/ } diff --git a/libs/spandsp/src/spandsp/fax_modems.h b/libs/spandsp/src/spandsp/fax_modems.h index 2ffb7be7c5..3a6adf28c1 100644 --- a/libs/spandsp/src/spandsp/fax_modems.h +++ b/libs/spandsp/src/spandsp/fax_modems.h @@ -59,6 +59,8 @@ extern "C" { #endif +SPAN_DECLARE(void) fax_modems_hdlc_accept(void *user_data, const uint8_t *msg, int len, int ok); + /*! Convert a FAX modem type to a short text description. \brief Convert a FAX modem type to a short text description. \param modem The modem code. diff --git a/libs/spandsp/src/t38_gateway.c b/libs/spandsp/src/t38_gateway.c index d89e21e0c4..402c7cded2 100644 --- a/libs/spandsp/src/t38_gateway.c +++ b/libs/spandsp/src/t38_gateway.c @@ -75,6 +75,10 @@ #include "spandsp/v27ter_rx.h" #include "spandsp/v17tx.h" #include "spandsp/v17rx.h" +#if defined(SPANDSP_SUPPORT_V34) +#include "spandsp/bitstream.h" +#include "spandsp/v34.h" +#endif #include "spandsp/super_tone_rx.h" #include "spandsp/modem_connect_tones.h" #include "spandsp/timezone.h" @@ -100,6 +104,10 @@ #include "spandsp/private/silence_gen.h" #include "spandsp/private/power_meter.h" #include "spandsp/private/fsk.h" +#if defined(SPANDSP_SUPPORT_V34) +#include "spandsp/private/bitstream.h" +#include "spandsp/private/v34.h" +#endif #include "spandsp/private/v17tx.h" #include "spandsp/private/v17rx.h" #include "spandsp/private/v27ter_tx.h" From 715731de9ae7f9971c1dd8fc4edc0ac69d61716b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 5 Dec 2013 11:35:33 -0600 Subject: [PATCH 162/656] FS-6026 --resolve --- src/mod/applications/mod_httapi/mod_httapi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 6ae3001804..7c61f52719 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -1473,7 +1473,6 @@ static switch_status_t httapi_sync(client_t *client) if (!put_file) { switch_curl_process_form_post_params(client->params, curl_handle, &formpost); - get_style_method = 1; } if (formpost) { From 6c5a17894c32df67955c816fd29d89bc8665042e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 5 Dec 2013 16:35:49 -0600 Subject: [PATCH 163/656] accept any payload when no payload map is present --- src/switch_rtp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 6e6c594f05..afd308b9c5 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4112,10 +4112,12 @@ static int jb_valid(switch_rtp_t *rtp_session) static int check_recv_payload(switch_rtp_t *rtp_session) { - int ok = 0; + int ok = 1; if (rtp_session->pmaps && *rtp_session->pmaps) { payload_map_t *pmap; + ok = 0; + switch_mutex_lock(rtp_session->flag_mutex); for (pmap = *rtp_session->pmaps; pmap && pmap->allocated; pmap = pmap->next) { if (!pmap->negotiated) { @@ -5040,11 +5042,13 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ rtp_session->recv_msg.header.pt != 13 && rtp_session->recv_msg.header.pt != rtp_session->recv_te && (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt)) { - int accept_packet = 0; + int accept_packet = 1; if (rtp_session->pmaps && *rtp_session->pmaps) { payload_map_t *pmap; + accept_packet = 0; + switch_mutex_lock(rtp_session->flag_mutex); for (pmap = *rtp_session->pmaps; pmap && pmap->allocated; pmap = pmap->next) { From eb3e84369237326bde74ece766ede5bcf990f4af Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sat, 7 Dec 2013 01:57:59 +0800 Subject: [PATCH 164/656] Eliminate a warning from valgrind, that might potentially be reporting actual trouble. --- libs/spandsp/src/plc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/spandsp/src/plc.c b/libs/spandsp/src/plc.c index 7b45dad988..cb40ea88e0 100644 --- a/libs/spandsp/src/plc.c +++ b/libs/spandsp/src/plc.c @@ -84,7 +84,7 @@ static __inline__ void normalise_history(plc_state_t *s) if (s->buf_ptr == 0) return; memcpy(tmp, s->history, sizeof(int16_t)*s->buf_ptr); - memcpy(s->history, s->history + s->buf_ptr, sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr)); + memmove(s->history, s->history + s->buf_ptr, sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr)); memcpy(s->history + PLC_HISTORY_LEN - s->buf_ptr, tmp, sizeof(int16_t)*s->buf_ptr); s->buf_ptr = 0; } From ac2bf8a4058cb3df40e79f89276eab4847f59ae3 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sun, 8 Dec 2013 01:39:00 +0800 Subject: [PATCH 165/656] Fixed a file permission in the ESL library --- libs/esl/src/include/esl_json.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 libs/esl/src/include/esl_json.h diff --git a/libs/esl/src/include/esl_json.h b/libs/esl/src/include/esl_json.h old mode 100755 new mode 100644 From 074b70b7dbf0c5ddfe1c05cd07d4836c2e51fa3e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 8 Dec 2013 07:09:40 +0500 Subject: [PATCH 166/656] comment --- support-d/.emacs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-d/.emacs b/support-d/.emacs index 9b7b191e8b..d895761034 100644 --- a/support-d/.emacs +++ b/support-d/.emacs @@ -6,7 +6,7 @@ ;(setq cperl-hairy t) (global-unset-key "\C-h") (global-set-key "\C-h" 'delete-backward-char) -(load "/usr/share/emacs/site-lisp/rng-auto.el") +;(load "/usr/share/emacs/site-lisp/rng-auto.el") (require 'cc-mode) (defun my-build-tab-stop-list (width) From f148aa9c3b490372b78f786134de9913300556d2 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 8 Dec 2013 00:31:11 +0000 Subject: [PATCH 167/656] Improve upgrade path to freeswitch-all That is to say, declare all appropriate Provides/Conflicts/Replaces for freeswitch-all and freeswitch-all-dbg by enumerating the binary packages that we're going to produce during the build. Conflicts is more appropriate than Breaks here as both packages will continue to provide the same files on an ongoing basis and we would like to force the removal of the other package. --- debian/bootstrap.sh | 123 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 11 deletions(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index edfe7f1077..3fc621aa4f 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -46,6 +46,33 @@ avoid_mods_squeeze=( formats/mod_vlc languages/mod_managed ) +manual_pkgs=( +freeswitch-all +freeswitch +libfreeswitch1 +freeswitch-meta-bare +freeswitch-meta-default +freeswitch-meta-vanilla +freeswitch-meta-sorbet +freeswitch-meta-all +freeswitch-meta-codecs +freeswitch-meta-conf +freeswitch-meta-lang +freeswitch-meta-mod-say +freeswitch-all-dbg +freeswitch-dbg +libfreeswitch1-dbg +libfreeswitch-dev +freeswitch-doc +freeswitch-init +freeswitch-sysvinit +freeswitch-systemd +freeswitch-lang +freeswitch-music +freeswitch-sounds +freeswitch-sounds-en +freeswitch-sounds-en-us +) err () { echo "$0 error: $1" >&2 @@ -61,6 +88,31 @@ xread () { return $ret } +intersperse () { + local sep="$1" + awk " + BEGIN { + first=1; + sep=\"${sep}\"; + }"' + /.*/ { + if (first == 0) { + printf "%s%s", sep, $0; + } else { + printf "%s", $0; + } + first=0; + } + END { printf "\n"; }' +} + +postfix () { + local px="$1" + awk " + BEGIN { px=\"${px}\"; }"' + /.*/ { printf "%s%s\n", $0, px; }' +} + avoid_mod_filter () { local x="avoid_mods_$codename[@]" local -a mods=("${avoid_mods[@]}" "${!x}") @@ -168,6 +220,60 @@ map_langs () { done } +map_pkgs () { + local fsx="$1" + for x in "${manual_pkgs[@]}"; do + $fsx $x + done + map_pkgs_confs () { $fsx "freeswitch-conf-${conf//_/-}"; } + map_confs map_pkgs_confs + map_pkgs_langs () { $fsx "freeswitch-lang-${lang//_/-}"; } + map_langs map_pkgs_langs + map_pkgs_mods () { + $fsx "freeswitch-mod-${module//_/-}" + $fsx "freeswitch-mod-${module//_/-}-dbg"; } + map_modules map_pkgs_mods +} + +list_pkgs () { + list_pkgs_thunk () { printf '%s\n' "$1"; } + map_pkgs list_pkgs_thunk +} + +list_freeswitch_all_pkgs () { + list_pkgs \ + | grep -v '^freeswitch-all$' \ + | grep -v -- '-dbg$' +} + +list_freeswitch_all_provides () { + list_freeswitch_all_pkgs \ + | intersperse ',\n ' +} + +list_freeswitch_all_replaces () { + list_freeswitch_all_pkgs \ + | postfix ' (<= ${binary:Version})' \ + | intersperse ',\n ' +} + +list_freeswitch_all_dbg_pkgs () { + list_pkgs \ + | grep -v '^freeswitch-all-dbg$' \ + | grep -- '-dbg$' +} + +list_freeswitch_all_dbg_provides () { + list_freeswitch_all_dbg_pkgs \ + | intersperse ',\n ' +} + +list_freeswitch_all_dbg_replaces () { + list_freeswitch_all_dbg_pkgs \ + | postfix ' (<= ${binary:Version})' \ + | intersperse ',\n ' +} + print_source_control () { cat <= 1.0.8), freeswitch-sounds-en-us-callie (>= 1.0.25) | freeswitch-sounds, @@ -647,6 +745,9 @@ Package: freeswitch-all-dbg Section: debug Priority: extra Architecture: any +Provides: $(list_freeswitch_all_dbg_provides) +Replaces: $(list_freeswitch_all_dbg_replaces) +Breaks: $(list_freeswitch_all_dbg_replaces) Depends: \${misc:Depends}, freeswitch (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") From 553bda996b1f19892cdfd9cfd20c00146e76b127 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sun, 8 Dec 2013 21:53:56 -0600 Subject: [PATCH 168/656] vs2010 reswig --- .../mod_managed/freeswitch_wrap.2010.cxx | 16 ++++++++++++---- .../languages/mod_managed/managed/swig.2010.cs | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 6b36513455..6a444f6ec1 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -12741,9 +12741,9 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_time_set_monotonic(int jarg1) { SWIGEXPORT void SWIGSTDCALL CSharp_switch_time_set_timerfd(int jarg1) { - switch_bool_t arg1 ; + int arg1 ; - arg1 = (switch_bool_t)jarg1; + arg1 = (int)jarg1; switch_time_set_timerfd(arg1); } @@ -14209,6 +14209,14 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ice_direction(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_core_session_debug_pool(void * jarg1) { + switch_stream_handle_t *arg1 = (switch_stream_handle_t *) 0 ; + + arg1 = (switch_stream_handle_t *)jarg1; + switch_core_session_debug_pool(arg1); +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_loadable_module_interface_module_name_set(void * jarg1, char * jarg2) { switch_loadable_module_interface *arg1 = (switch_loadable_module_interface *) 0 ; char *arg2 = (char *) 0 ; @@ -35686,7 +35694,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_MAX_CAND_get() { int jresult ; int result; - result = (int)(25); + result = (int)(50); jresult = result; return jresult; } @@ -35702,7 +35710,7 @@ SWIGEXPORT void SWIGSTDCALL CSharp_ice_t_cands_set(void * jarg1, void * jarg2) { icand_t (*inp)[2] = (icand_t (*)[2])(arg2); icand_t (*dest)[2] = (icand_t (*)[2])(arg1->cands); size_t ii = 0; - for (; ii < 25; ++ii) { + for (; ii < 50; ++ii) { icand_t *ip = inp[ii]; icand_t *dp = dest[ii]; size_t jj = 0; diff --git a/src/mod/languages/mod_managed/managed/swig.2010.cs b/src/mod/languages/mod_managed/managed/swig.2010.cs index 44cc42ee90..631a7fcf8f 100644 --- a/src/mod/languages/mod_managed/managed/swig.2010.cs +++ b/src/mod/languages/mod_managed/managed/swig.2010.cs @@ -2763,8 +2763,8 @@ public class freeswitch { freeswitchPINVOKE.switch_time_set_monotonic((int)enable); } - public static void switch_time_set_timerfd(switch_bool_t enable) { - freeswitchPINVOKE.switch_time_set_timerfd((int)enable); + public static void switch_time_set_timerfd(int enable) { + freeswitchPINVOKE.switch_time_set_timerfd(enable); } public static void switch_time_set_nanosleep(switch_bool_t enable) { @@ -3160,6 +3160,10 @@ public class freeswitch { return ret; } + public static void switch_core_session_debug_pool(switch_stream_handle stream) { + freeswitchPINVOKE.switch_core_session_debug_pool(switch_stream_handle.getCPtr(stream)); + } + public static switch_status_t switch_loadable_module_init(switch_bool_t autoload) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_loadable_module_init((int)autoload); return ret; @@ -10723,6 +10727,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ice_direction")] public static extern int switch_ice_direction(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_debug_pool")] + public static extern void switch_core_session_debug_pool(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_interface_module_name_set")] public static extern void switch_loadable_module_interface_module_name_set(HandleRef jarg1, string jarg2); @@ -26726,6 +26733,7 @@ public enum switch_channel_flag_t { CF_VIDEO_ECHO, CF_SLA_INTERCEPT, CF_VIDEO_BREAK, + CF_MEDIA_PAUSE, CF_FLAG_MAX } @@ -35305,6 +35313,8 @@ public enum switch_rtp_flag_t { SWITCH_RTP_FLAG_KILL_JB, SWITCH_RTP_FLAG_VIDEO_BREAK, SWITCH_RTP_FLAG_PAUSE, + SWITCH_RTP_FLAG_FIR, + SWITCH_RTP_FLAG_PLI, SWITCH_RTP_FLAG_INVALID } From 9caae64f37bfdc8b17761926e8711e0f85963c35 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 9 Dec 2013 09:18:38 +0000 Subject: [PATCH 169/656] Correct shlibs of freeswitch-all wrt libfreeswitch1 The freeswitch-all package provides libfreeswitch1, so any shlibs-generated dependency should be for libfreeswitch1 rather than freeswitch-all. Because dh_shlibdeps / dpkg-shlibdeps searches for shlibs files in debian/*/DEBIAN/ it was sometimes using freeswitch-all rather than libfreeswitch1 to satisfy dependencies for freeswitch.so.1. FS-6029 --resolve --- debian/rules | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/rules b/debian/rules index 7d7d50fd71..0eb01ee422 100755 --- a/debian/rules +++ b/debian/rules @@ -106,6 +106,12 @@ override_dh_installinit: dh_installinit -pfreeswitch-sysvinit --name=freeswitch dh_installinit -pfreeswitch-all --name=freeswitch +override_dh_makeshlibs: + dh_makeshlibs + sed \ + -e '/^libfreeswitch 1/{s/freeswitch-all/libfreeswitch1/g}' \ + -i debian/freeswitch-all/DEBIAN/shlibs + debian-bootstrap: debian/.stamp-bootstrap debian/.stamp-bootstrap: (cd debian && ./bootstrap.sh) From 3f064220b99330a12839ac377b20c595143b04e7 Mon Sep 17 00:00:00 2001 From: Nathan Neulinger Date: Mon, 9 Dec 2013 08:54:54 -0600 Subject: [PATCH 170/656] FS-6024 --resolve --- src/mod/endpoints/mod_skinny/skinny_server.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 76486633ba..aaf7586daf 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -849,7 +849,25 @@ switch_status_t skinny_session_unhold_line(switch_core_session_t *session, liste send_set_ringer(listener, SKINNY_RING_OFF, SKINNY_RING_FOREVER, 0, tech_pvt->call_id); send_set_speaker_mode(listener, SKINNY_SPEAKER_ON); send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_RING_OUT, 0xffff); - skinny_session_start_media(session, listener, line_instance); + + send_stop_tone(listener, line_instance, tech_pvt->call_id); + send_open_receive_channel(listener, + tech_pvt->call_id, /* uint32_t conference_id, */ + tech_pvt->call_id, /* uint32_t pass_thru_party_id, */ + 20, /* uint32_t ms_per_packet, */ + SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */ + 0, /* uint32_t echo_cancel_type, */ + 0, /* uint32_t g723_bitrate, */ + 0, /* uint32_t conference_id2, */ + 0 /* uint32_t reserved[10] */ + ); + + skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_CONNECTED); + send_select_soft_keys(listener, line_instance, tech_pvt->call_id, SKINNY_KEY_SET_CONNECTED, 0xffff); + + send_display_prompt_status_textid(listener, 0, SKINNY_TEXTID_CONNECTED, line_instance, tech_pvt->call_id); + skinny_session_send_call_info(session, listener, line_instance); + return SWITCH_STATUS_SUCCESS; } From 0174aba5aff5aa430700cc076edb8b196d4146a2 Mon Sep 17 00:00:00 2001 From: Nathan Neulinger Date: Mon, 9 Dec 2013 09:01:02 -0600 Subject: [PATCH 171/656] mod_skinny: move hardwired ptime to a define so it's in one place --- src/mod/endpoints/mod_skinny/skinny_protocol.h | 4 ++++ src/mod/endpoints/mod_skinny/skinny_server.c | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 8a5178302e..870b4c578a 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -39,6 +39,10 @@ /*****************************************************************************/ /* SKINNY TYPES */ /*****************************************************************************/ + +/* Hardcode ptime in one place until we make it dynamic */ +#define SKINNY_PTIME 20 + typedef enum { SKINNY_CODEC_NONE = 0, SKINNY_CODEC_NONSTANDARD = 1, diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index aaf7586daf..b9ec3de21b 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -788,7 +788,7 @@ switch_status_t skinny_session_start_media(switch_core_session_t *session, liste send_open_receive_channel(listener, tech_pvt->call_id, /* uint32_t conference_id, */ tech_pvt->call_id, /* uint32_t pass_thru_party_id, */ - 20, /* uint32_t ms_per_packet, */ + SKINNY_PTIME, /* uint32_t ms_per_packet, */ SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */ 0, /* uint32_t echo_cancel_type, */ 0, /* uint32_t g723_bitrate, */ @@ -854,7 +854,7 @@ switch_status_t skinny_session_unhold_line(switch_core_session_t *session, liste send_open_receive_channel(listener, tech_pvt->call_id, /* uint32_t conference_id, */ tech_pvt->call_id, /* uint32_t pass_thru_party_id, */ - 20, /* uint32_t ms_per_packet, */ + SKINNY_PTIME, /* uint32_t ms_per_packet, */ SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */ 0, /* uint32_t echo_cancel_type, */ 0, /* uint32_t g723_bitrate, */ @@ -1830,7 +1830,7 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste /* Codec */ tech_pvt->iananame = "PCMU"; /* TODO */ - tech_pvt->codec_ms = 20; /* TODO */ + tech_pvt->codec_ms = SKINNY_PTIME; /* TODO */ tech_pvt->rm_rate = 8000; /* TODO */ tech_pvt->rm_fmtp = NULL; /* TODO */ tech_pvt->agreed_pt = (switch_payload_t) 0; /* TODO */ @@ -1879,7 +1879,7 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste tech_pvt->party_id, /* uint32_t pass_thru_party_id, */ addr.s_addr, /* uint32_t remote_ip, */ tech_pvt->local_sdp_audio_port, /* uint32_t remote_port, */ - 20, /* uint32_t ms_per_packet, */ + SKINNY_PTIME, /* uint32_t ms_per_packet, */ SKINNY_CODEC_ULAW_64K, /* uint32_t payload_capacity, */ 184, /* uint32_t precedence, */ 0, /* uint32_t silence_suppression, */ From 9d70d99d892bb6b224c80337265fb875e14408f6 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 9 Dec 2013 11:09:50 -0500 Subject: [PATCH 172/656] mod_mongo: use C++ driver pooling, added support for socket timeout --- conf/vanilla/autoload_configs/mongo.conf.xml | 3 +- src/mod/applications/mod_mongo/Makefile | 7 +- .../conf/autoload_configs/mongo.conf.xml | 3 +- src/mod/applications/mod_mongo/mod_mongo.cpp | 158 +++++++------ src/mod/applications/mod_mongo/mod_mongo.h | 75 ------- src/mod/applications/mod_mongo/mongo_conn.cpp | 211 ------------------ 6 files changed, 103 insertions(+), 354 deletions(-) delete mode 100644 src/mod/applications/mod_mongo/mod_mongo.h delete mode 100644 src/mod/applications/mod_mongo/mongo_conn.cpp diff --git a/conf/vanilla/autoload_configs/mongo.conf.xml b/conf/vanilla/autoload_configs/mongo.conf.xml index 8423645e95..72fffafbb7 100644 --- a/conf/vanilla/autoload_configs/mongo.conf.xml +++ b/conf/vanilla/autoload_configs/mongo.conf.xml @@ -7,8 +7,9 @@ foo/server:port,server:port SET --> - + + - + + - - - - - - - diff --git a/conf/rayo/autoload_configs/hash.conf.xml b/conf/rayo/autoload_configs/hash.conf.xml deleted file mode 100644 index 95b7928775..0000000000 --- a/conf/rayo/autoload_configs/hash.conf.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/conf/rayo/autoload_configs/lua.conf.xml b/conf/rayo/autoload_configs/lua.conf.xml deleted file mode 100644 index 1eb594f0b5..0000000000 --- a/conf/rayo/autoload_configs/lua.conf.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/conf/rayo/autoload_configs/memcache.conf.xml b/conf/rayo/autoload_configs/memcache.conf.xml deleted file mode 100644 index dc0173f986..0000000000 --- a/conf/rayo/autoload_configs/memcache.conf.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/conf/rayo/autoload_configs/modules.conf.xml b/conf/rayo/autoload_configs/modules.conf.xml index 604bc4e12c..e0d81b34fa 100644 --- a/conf/rayo/autoload_configs/modules.conf.xml +++ b/conf/rayo/autoload_configs/modules.conf.xml @@ -18,8 +18,6 @@ - - @@ -33,6 +31,8 @@ + + @@ -45,9 +45,6 @@ - - - diff --git a/freeswitch.spec b/freeswitch.spec index d1ce880237..37f66cdf53 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -22,6 +22,7 @@ # Marc Olivier Chouinard # Raymond Chandler # Ken Rice +# Chris Rienzo # # Maintainer(s): Ken Rice # @@ -33,6 +34,8 @@ %define build_py26_esl 0 %define build_timerfd 0 %define build_mod_esl 0 +%define build_mod_rayo 1 +%define build_mod_ssml 1 %{?with_sang_tc:%define build_sng_tc 1 } %{?with_sang_isdn:%define build_sng_isdn 1 } @@ -977,6 +980,17 @@ Requires: %{name} = %{version}-%{release} %description event-json-cdr JSON CDR Logger for FreeSWITCH. +%if %{build_mod_rayo} +%package event-rayo +Summary: Rayo (XMPP 3PCC) server for the FreeSWITCH open source telephony platform +Group: System/Libraries +Requires: %{name} = %{version}-%{release} + +%description event-rayo +Rayo 3PCC for FreeSWITCH. http://rayo.org http://xmpp.org/extensions/xep-0327.html +Rayo is an XMPP protocol extension for third-party control of telephone calls. +%endif + %package event-snmp Summary: SNMP stats reporter for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1040,6 +1054,16 @@ Requires: %{name} = %{version}-%{release} Mod Shout is a FreeSWITCH module to allow you to stream audio from MP3s or a i shoutcast stream. +%if %{build_mod_ssml} +%package format-ssml +Summary: Adds Speech Synthesis Markup Language (SSML) parser format for the FreeSWITCH open source telephony platform +Group: System/Libraries +Requires: %{name} = %{version}-%{release} + +%description format-ssml +mod_ssml is a FreeSWITCH module that renders SSML into audio. This module requires a text-to-speech module for speech synthesis. +%endif + %package format-tone-stream Summary: Implements TGML Tone Generation for the FreeSWITCH open source telephony platform Group: System/Libraries @@ -1376,6 +1400,9 @@ EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv event_handlers/mod_cdr_mongodb event_handlers/mod_erlang_event event_handlers/mod_event_multicast \ event_handlers/mod_event_socket event_handlers/mod_json_cdr \ event_handlers/mod_snmp" +%if %{build_mod_rayo} +EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo" +%endif #### BUILD ISSUES NET RESOLVED FOR RELEASE event_handlers/mod_event_zmq ###################################################################################################################### @@ -1385,6 +1412,9 @@ EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_cdr_pg_csv ###################################################################################################################### FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_portaudio_stream \ formats/mod_shell_stream formats/mod_shout formats/mod_sndfile formats/mod_tone_stream" +%if %{build_mod_ssml} +FORMATS_MODULES+=" formats/mod_ssml" +%endif ###################################################################################################################### # @@ -1704,8 +1734,7 @@ fi %{LIBDIR}/*.a %{LIBDIR}/*.la %{PKGCONFIGDIR}/* -%{MODINSTDIR}/*.a -%{MODINSTDIR}/*.la +%{MODINSTDIR}/*.*a %{INCLUDEDIR}/*.h @@ -1743,6 +1772,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/event_socket.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/fax.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/fifo.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/format_cdr.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/hash.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/httapi.conf.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/http_cache.conf.xml @@ -2189,6 +2219,12 @@ fi %defattr(-, freeswitch, daemon) %{MODINSTDIR}/mod_json_cdr.so* +%if %{build_mod_rayo} +%files event-rayo +%defattr(-, freeswitch, daemon) +%{MODINSTDIR}/mod_rayo.so* +%endif + %files event-snmp %defattr(-, freeswitch, daemon) %{MODINSTDIR}/mod_snmp.so* @@ -2219,6 +2255,12 @@ fi %defattr(-, freeswitch, daemon) %{MODINSTDIR}/mod_shout.so* +%if %{build_mod_ssml} +%files format-ssml +%defattr(-, freeswitch, daemon) +%{MODINSTDIR}/mod_ssml.so* +%endif + %files format-tone-stream %defattr(-, freeswitch, daemon) %{MODINSTDIR}/mod_tone_stream.so* @@ -2385,6 +2427,9 @@ fi # ###################################################################################################################### %changelog +* Mon Dec 09 2013 - crienzo@grasshopper.com +- Add mod_ssml, mod_rayo +- Fix build on master * Thu Jun 28 2013 - krice@freeswitch.org - Add module for VP8 * Thu Jun 19 2013 - krice@freeswitch.org From d9a8dd0bb64a2859df9feb6abbff4d38610a8da2 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 9 Dec 2013 17:41:01 -0500 Subject: [PATCH 179/656] build: added freeswitch-config-rayo package and script to build it --- freeswitch-config-rayo.spec | 179 ++++++++++++++++++++++++++++++++++++ scripts/ci/config-rayo.sh | 26 ++++++ 2 files changed, 205 insertions(+) create mode 100644 freeswitch-config-rayo.spec create mode 100755 scripts/ci/config-rayo.sh diff --git a/freeswitch-config-rayo.spec b/freeswitch-config-rayo.spec new file mode 100644 index 0000000000..d5f951da50 --- /dev/null +++ b/freeswitch-config-rayo.spec @@ -0,0 +1,179 @@ +###################################################################################################################### +# +# freeswitch-config-rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application +# Copyright (C) 2013, Grasshopper +# +# Version: MPL 1.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is freeswitch-config-rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application +# +# The Initial Developer of the Original Code is Grasshopper +# Portions created by the Initial Developer are Copyright (C) +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Chris Rienzo +# +# freeswitch-rayo-config -- RPM packaging for Rayo Server configuration +# +###################################################################################################################### + +%define version %{VERSION_NUMBER} +%define release %{BUILD_NUMBER} + +%define fsname freeswitch + +%define PREFIX %{_prefix} +%define EXECPREFIX %{_exec_prefix} +%define BINDIR %{_bindir} +%define SBINDIR %{_sbindir} +%define LIBEXECDIR %{_libexecdir}/%fsname +%define SYSCONFDIR %{_sysconfdir}/%fsname +%define SHARESTATEDIR %{_sharedstatedir}/%fsname +%define LOCALSTATEDIR %{_localstatedir}/lib/%fsname +%define LIBDIR %{_libdir} +%define INCLUDEDIR %{_includedir} +%define _datarootdir %{_prefix}/share +%define DATAROOTDIR %{_datarootdir} +%define DATADIR %{_datadir} +%define INFODIR %{_infodir} +%define LOCALEDIR %{_datarootdir}/locale +%define MANDIR %{_mandir} +%define DOCDIR %{_defaultdocdir}/%fsname +%define HTMLDIR %{_defaultdocdir}/%fsname/html +%define DVIDIR %{_defaultdocdir}/%fsname/dvi +%define PDFDIR %{_defaultdocdir}/%fsname/pdf +%define PSDIR %{_defaultdocdir}/%fsname/ps +%define LOGFILEDIR /var/log/%fsname +%define MODINSTDIR %{_libdir}/%fsname/mod +%define RUNDIR %{_localstatedir}/run/%fsname +%define DBDIR %{LOCALSTATEDIR}/db +%define HTDOCSDIR %{_datarootdir}/%fsname/htdocs +%define SOUNDSDIR %{_datarootdir}/%fsname/sounds +%define GRAMMARDIR %{_datarootdir}/%fsname/grammar +%define SCRIPTDIR %{_datarootdir}/%fsname/scripts +%define RECORDINGSDIR %{LOCALSTATEDIR}/recordings +%define PKGCONFIGDIR %{_datarootdir}/%fsname/pkgconfig +%define HOMEDIR %{LOCALSTATEDIR} + +Name: freeswitch-config-rayo +Version: %{version} +Release: %{release}%{?dist} +License: MPL1.1 +Summary: Rayo configuration for the FreeSWITCH Open Source telephone platform. +Group: System/Libraries +Packager: Chris Rienzo +URL: http://www.freeswitch.org/ +Source0: freeswitch-%{version}.tar.bz2 +Requires: freeswitch = %{version} +Requires: freeswitch-application-conference +Requires: freeswitch-application-esf +Requires: freeswitch-application-expr +Requires: freeswitch-application-fsv +Requires: freeswitch-application-http-cache +Requires: freeswitch-asrtts-flite +Requires: freeswitch-asrtts-pocketsphinx +Requires: freeswitch-codec-celt +Requires: freeswitch-codec-h26x +Requires: freeswitch-codec-ilbc +Requires: freeswitch-codec-opus +Requires: freeswitch-codec-speex +Requires: freeswitch-codec-vp8 +Requires: freeswitch-event-rayo +Requires: freeswitch-format-local-stream +Requires: freeswitch-format-mod-shout +Requires: freeswitch-format-shell-stream +Requires: freeswitch-format-ssml +Requires: freeswitch-sounds-music-8000 +Requires: freeswitch-sounds-music-16000 +Requires: freeswitch-sounds-music-32000 +Requires: freeswitch-sounds-music-48000 +Requires: freeswitch-lang-en +Requires: freeswitch-sounds-en-us-callie-8000 +Requires: freeswitch-sounds-en-us-callie-16000 +Requires: freeswitch-sounds-en-us-callie-32000 +Requires: freeswitch-sounds-en-us-callie-48000 +BuildRequires: bash +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +%description +FreeSWITCH rayo server implementation. + +%prep +%setup -b0 -q -n freeswitch-%{version} + +%build + +%install +%{__rm} -rf %{buildroot} +%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR} +%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/autoload_configs +%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/dialplan +%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/sip_profiles +%{__install} -d -m 0750 %{buildroot}/%{SYSCONFDIR}/directory +%{__cp} -prv ./conf/rayo/*.{xml,types,pem} %{buildroot}/%{SYSCONFDIR}/ +%{__cp} -prv ./conf/rayo/{autoload_configs,dialplan} %{buildroot}/%{SYSCONFDIR}/ +%{__cp} -prv ./conf/rayo/sip_profiles/external.xml %{buildroot}/%{SYSCONFDIR}/sip_profiles +%{__cp} -prv ./conf/rayo/sip_profiles/external %{buildroot}/%{SYSCONFDIR}/sip_profiles +%{__cp} -prv ./conf/rayo/directory %{buildroot}/%{SYSCONFDIR}/ + +%postun + +%clean +%{__rm} -rf %{buildroot} + +%files +%defattr(-,freeswitch,daemon) +%dir %attr(0750, freeswitch, daemon) %{SYSCONFDIR} +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/cacert.pem +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/mime.types +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/acl.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/cdr_csv.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/conference.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/console.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/event_socket.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/http_cache.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/local_stream.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/logfile.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/modules.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/pocketsphinx.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/post_load_modules.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/presence_map.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/rayo.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/shout.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/sofia.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/spandsp.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/ssml.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/switch.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/autoload_configs/timezones.conf.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/dialplan/public.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/directory/default.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/directory/default/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/sip_profiles/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{SYSCONFDIR}/sip_profiles/external/*.xml + +### END OF config-rayo + +###################################################################################################################### +# +# Changelog +# +###################################################################################################################### +%changelog +* Mon Jun 03 2013 - crienzo@grasshopper.com +- Added users and internal profile for softphone testing +* Wed May 08 2013 - crienzo@grasshopper.com +- Initial revision + diff --git a/scripts/ci/config-rayo.sh b/scripts/ci/config-rayo.sh new file mode 100755 index 0000000000..c346f5e0ed --- /dev/null +++ b/scripts/ci/config-rayo.sh @@ -0,0 +1,26 @@ +#!/bin/sh +##### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*- + +src_repo="$(pwd)" + +if [ ! -d .git ]; then + echo "error: must be run from within the top level of a FreeSWITCH git tree." 1>&2 + exit 1; +fi + +rpmbuild --define "VERSION_NUMBER $1" \ + --define "BUILD_NUMBER $2" \ + --define "_topdir %(pwd)/rpmbuild" \ + --define "_rpmdir %{_topdir}" \ + --define "_srcrpmdir %{_topdir}" \ + -ba freeswitch-config-rayo.spec + +mkdir $src_repo/RPMS +mv $src_repo/rpmbuild/*/*.rpm $src_repo/RPMS/. + +cat 1>&2 < Date: Tue, 10 Dec 2013 03:42:12 +0500 Subject: [PATCH 180/656] FS-6033 --resolve --- src/switch_ivr_play_say.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 97f553d733..47451c3ca6 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -389,31 +389,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se const char *prefix, *var; + if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + prefix = switch_channel_get_variable(channel, "sound_prefix"); if (!prefix) { prefix = SWITCH_GLOBAL_dirs.sounds_dir; } + if (!switch_channel_media_ready(channel)) { + return SWITCH_STATUS_FALSE; + } + switch_core_session_get_read_impl(session, &read_impl); if (!(divisor = read_impl.actual_samples_per_second / 8000)) { divisor = 1; } - - if (!switch_channel_ready(channel)) { - return SWITCH_STATUS_FALSE; - } - - if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; - } - - if (!switch_channel_media_ready(channel)) { - return SWITCH_STATUS_FALSE; - } - arg_recursion_check_start(args); if (!fh) { From a5647414e463926e2b6a69827ee7c5d13880b2db Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 7 Dec 2013 21:14:26 +0000 Subject: [PATCH 181/656] Deal correctly with spaces in SWITCH_VERSION_REVISION_HUMAN This affects the set_fs_ver bash function and the ./build/set-fs-version.sh script. Previously we were failing to quote the value of SWITCH_VERSION_REVISION_HUMAN when inserting it into configure.in. When it contains spaces, which it often does, this results in a malformed line in the generated configure script, which results in the define in src/include/switch_version.h.in being left unset. --- scripts/ci/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci/common.sh b/scripts/ci/common.sh index a1e97c6064..adb8d56d80 100755 --- a/scripts/ci/common.sh +++ b/scripts/ci/common.sh @@ -108,7 +108,7 @@ set_fs_ver () { if [ -n "$rev" ]; then [ -n "$hrev" ] || hrev="$rev" sed -e "s|\(AC_SUBST(SWITCH_VERSION_REVISION, \[\).*\(\])\)|\1$rev\2|" \ - -e "s|\(AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, \[\).*\(\])\)|\1$hrev\2|" \ + -e "s|\(AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, \[\).*\(\])\)|\1'$hrev'\2|" \ -e "s|#\(AC_SUBST(SWITCH_VERSION_REVISION\)|\1|" \ -e "s|#\(AC_SUBST(SWITCH_VERSION_REVISION_HUMAN\)|\1|" \ configure.in > configure.in.$$ From 8099af65647d01dc5e2d65a50626a4299fc7d70c Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 10 Dec 2013 03:53:17 +0000 Subject: [PATCH 182/656] Cleanup whitespace in debian/ --- debian/AUTHORS | 1 - debian/bootstrap.sh | 2 +- debian/control-modules | 1 - debian/copyright | 4 ++-- debian/freeswitch-systemd.freeswitch.service | 1 - debian/rules | 1 - debian/util.sh | 1 - 7 files changed, 3 insertions(+), 8 deletions(-) diff --git a/debian/AUTHORS b/debian/AUTHORS index 2145c58864..838dabde3c 100644 --- a/debian/AUTHORS +++ b/debian/AUTHORS @@ -23,4 +23,3 @@ Thanks-to: Steven Ayre Thanks-to: William King # for moral support and small tweaks - diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 3fc621aa4f..8f12a9fc3f 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -1018,7 +1018,7 @@ print_edit_warning () { } gencontrol_per_mod () { - print_mod_control "$module_name" "$description" "$long_description" >> control + print_mod_control "$module_name" "$description" "$long_description" >> control } gencontrol_per_cat () { diff --git a/debian/control-modules b/debian/control-modules index cd7acb2c73..4ece17626a 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -700,4 +700,3 @@ Description: mod_xml_rpc Module: xml_int/mod_xml_scgi Description: mod_xml_scgi Adds mod_xml_scgi. - diff --git a/debian/copyright b/debian/copyright index d7ea35053f..278992caa0 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1427,7 +1427,7 @@ Files: libs/js/nsprpub/pr/tests/tmocon.c libs/js/nsprpub/pr/src/md/unix/os_ReliantUNIX.s libs/js/nsprpub/pr/src/md/unix/os_Darwin_ppc.s libs/js/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s - libs/js/nsprpub/pr/src/md/unix/os_Linux_ia64.s + libs/js/nsprpub/pr/src/md/unix/os_Linux_ia64.s libs/js/nsprpub/pr/tests/testfile.c libs/js/nsprpub/pr/src/md/unix/os_Darwin_x86.s libs/js/nsprpub/pr/src/md/unix/os_AIX.s @@ -1958,7 +1958,7 @@ License: LGPL Files: libs/libwebsockets/win32port/zlib/* Copyright: 1995-2010 Jean-loup Gailly - 1995-2010 Mark Adler + 1995-2010 Mark Adler 1995-2010 Jean-loup Gailly and Mark Adler 1995-2010 Jean-loup Gailly and Mark Adler "; License: zlib/libpng diff --git a/debian/freeswitch-systemd.freeswitch.service b/debian/freeswitch-systemd.freeswitch.service index 1e7d2fcad1..3a734e3b37 100644 --- a/debian/freeswitch-systemd.freeswitch.service +++ b/debian/freeswitch-systemd.freeswitch.service @@ -32,4 +32,3 @@ UMask=0007 [Install] WantedBy=multi-user.target - diff --git a/debian/rules b/debian/rules index 0eb01ee422..e2586a455c 100755 --- a/debian/rules +++ b/debian/rules @@ -133,4 +133,3 @@ binary-quicktest: echo "applications/mod_commands" > debian/modules.conf (cd debian && ./bootstrap.sh) dh binary - diff --git a/debian/util.sh b/debian/util.sh index 66231c3d82..94ef0e0791 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -455,4 +455,3 @@ case "$cmd" in create-orig) create_orig "$@" ;; *) usage ;; esac - From 58d0d3d4a8730281e8cc6aae70c61e5f7e91b3da Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 10 Dec 2013 18:19:36 +0000 Subject: [PATCH 183/656] Cleanup whitespace --- docs/SubmittingPatches | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/SubmittingPatches b/docs/SubmittingPatches index e839ff128d..3ac732d349 100644 --- a/docs/SubmittingPatches +++ b/docs/SubmittingPatches @@ -108,10 +108,9 @@ submitted to JIRA. You can also reach us on freenode.net at: > #freeswitch-dev - + Finally, feel free to join us in our weekly conference call. Many of the core developers are often on the call and you'll have an opportunity at the beginning or end of the call to ask your questions: > http://wiki.freeswitch.org/wiki/Weekly_Conference_Call - From d2f8cf40bc33edc00a5f77f13283fc9233e032e5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 10 Dec 2013 23:48:09 +0500 Subject: [PATCH 184/656] FS-6006 --- src/switch_core_state_machine.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 6de6b9798e..0005905deb 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -467,7 +467,8 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) switch_channel_set_running_state(session->channel, state); switch_channel_clear_flag(session->channel, CF_TRANSFER); switch_channel_clear_flag(session->channel, CF_REDIRECT); - + switch_ivr_parse_all_messages(session); + if (session->endpoint_interface->io_routines->state_run) { rstatus = session->endpoint_interface->io_routines->state_run(session); } From ef730b75aa40d99d0ef1b9465fd2cdef605d64cb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 11 Dec 2013 00:04:26 +0500 Subject: [PATCH 185/656] FS-5987 pushing the patch now since no matter what its better than before --- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia.c | 60 ++++++++---- src/mod/endpoints/mod_sofia/sofia_presence.c | 37 +++++--- src/mod/endpoints/mod_sofia/sofia_reg.c | 99 ++++++++++++-------- 4 files changed, 128 insertions(+), 70 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 952fce2f9f..f80539684a 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -164,7 +164,6 @@ typedef struct sofia_dispatch_event_s { struct sofia_private { char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1]; - sofia_gateway_t *gateway; char gateway_name[256]; char auth_gateway_name[256]; char *call_id; @@ -422,6 +421,7 @@ typedef enum { struct sofia_gateway_subscription { sofia_gateway_t *gateway; + sofia_private_t *sofia_private; nua_handle_t *nh; char *expires_str; char *event; /* eg, 'message-summary' to subscribe to MWI events */ diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f9fc330c71..ad581d877e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -337,6 +337,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, switch_event_t *s_event = NULL; sofia_gateway_subscription_t *gw_sub_ptr; int sub_state; + sofia_gateway_t *gateway = NULL; tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END()); @@ -445,19 +446,25 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, } } - if (!sofia_private || !sofia_private->gateway) { + if (!sofia_private || zstr(sofia_private->gateway_name)) { if (profile->debug) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Gateway information missing Subscription Event: %s\n", sip->sip_event->o_type); } goto error; } + + + if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Gateway information missing\n"); + goto error; + } /* find the corresponding gateway subscription (if any) */ - if (!(gw_sub_ptr = sofia_find_gateway_subscription(sofia_private->gateway, sip->sip_event->o_type))) { + if (!(gw_sub_ptr = sofia_find_gateway_subscription(gateway, sip->sip_event->o_type))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Could not find gateway subscription. Gateway: %s. Subscription Event: %s\n", - sofia_private->gateway->name, sip->sip_event->o_type); + gateway->name, sip->sip_event->o_type); goto error; } @@ -466,17 +473,28 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, goto error; } + if (sip->sip_subscription_state && sip->sip_subscription_state->ss_expires) { + int delta = atoi(sip->sip_subscription_state->ss_expires); + + delta /= 2; + + if (delta < 1) { + delta = 1; + } + gw_sub_ptr->expires = switch_epoch_time_now(NULL) + delta; + } + /* dispatch freeswitch event */ if (switch_event_create(&s_event, SWITCH_EVENT_NOTIFY_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "event", sip->sip_event->o_type); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "pl_data", sip->sip_payload ? sip->sip_payload->pl_data : ""); if ( sip->sip_content_type != NULL ) switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_content_type", sip->sip_content_type->c_type); - switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", sofia_private->gateway->profile->sip_port); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "port", "%d", gateway->profile->sip_port); switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "module_name", "mod_sofia"); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", sofia_private->gateway->profile->name); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", sofia_private->gateway->profile->url); - switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "gateway_name", sofia_private->gateway->name); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_name", gateway->profile->name); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile_uri", gateway->profile->url); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "gateway_name", gateway->name); if ( sip->sip_call_info != NULL ) { sip_call_info_t *call_info = sip->sip_call_info; int cur_len = 0; @@ -565,12 +583,16 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, end: - if (sub_state == nua_substate_terminated && sofia_private && sofia_private != &mod_sofia_globals.destroy_private && + if (!gateway && sub_state == nua_substate_terminated && sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) { sofia_private->destroy_nh = 1; sofia_private->destroy_me = 1; } + if (gateway) { + sofia_reg_release_gateway(gateway); + } + } void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, @@ -1049,9 +1071,9 @@ static void our_sofia_event_callback(nua_event_t event, if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) { - if ((gateway = sofia_private->gateway)) { - /* Released in sofia_reg_release_gateway() */ - if (sofia_reg_gateway_rdlock(gateway) != SWITCH_STATUS_SUCCESS) { + + if (!zstr(sofia_private->gateway_name)) { + if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) { return; } } else if (!zstr(sofia_private->uuid)) { @@ -1499,9 +1521,16 @@ static void our_sofia_event_callback(nua_event_t event, case nua_r_authenticate: if (status >= 500) { - if (sofia_private && sofia_private->gateway) { - nua_handle_destroy(sofia_private->gateway->nh); - sofia_private->gateway->nh = NULL; + if (sofia_private && !zstr(sofia_private->gateway_name)) { + sofia_gateway_t *gateway = NULL; + + if ((gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) { + nua_handle_bind(gateway->nh, NULL); + gateway->sofia_private = NULL; + nua_handle_destroy(gateway->nh); + gateway->nh = NULL; + sofia_reg_release_gateway(gateway); + } } else { nua_handle_destroy(nh); } @@ -2325,10 +2354,9 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread if (++gateway_loops >= GATEWAY_SECONDS) { sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL)); + sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL)); gateway_loops = 0; } - - sofia_sub_check_gateway(profile, time(NULL)); } switch_yield(1000000); diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 747f4491e5..dd0fe1ac95 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -4285,6 +4285,7 @@ void sofia_presence_handle_sip_r_subscribe(int status, { sip_event_t const *o = NULL; sofia_gateway_subscription_t *gw_sub_ptr; + sofia_gateway_t *gateway = NULL; if (!sip) { return; @@ -4297,18 +4298,25 @@ void sofia_presence_handle_sip_r_subscribe(int status, return; } - if (!sofia_private || !sofia_private->gateway) { + if (!sofia_private || zstr(sofia_private->gateway_name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Gateway information missing\n"); return; } - /* Find the subscription if one exists */ - if (!(gw_sub_ptr = sofia_find_gateway_subscription(sofia_private->gateway, o->o_type))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not find gateway subscription. Gateway: %s. Subscription Event: %s\n", - sofia_private->gateway->name, o->o_type); + + if (!(gateway = sofia_reg_find_gateway(sofia_private->gateway_name))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Gateway information missing\n"); return; } + + /* Find the subscription if one exists */ + if (!(gw_sub_ptr = sofia_find_gateway_subscription(gateway, o->o_type))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Could not find gateway subscription. Gateway: %s. Subscription Event: %s\n", + gateway->name, o->o_type); + goto end; + } + /* Update the subscription status for the subscription */ switch (status) { case 200: @@ -4326,19 +4334,22 @@ void sofia_presence_handle_sip_r_subscribe(int status, default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "status (%d) != 200, updated state to SUB_STATE_FAILED.\n", status); gw_sub_ptr->state = SUB_STATE_FAILED; + gw_sub_ptr->expires = switch_epoch_time_now(NULL); + gw_sub_ptr->retry = switch_epoch_time_now(NULL); - if (sofia_private) { - if (gw_sub_ptr->nh) { - nua_handle_bind(gw_sub_ptr->nh, NULL); - nua_handle_destroy(gw_sub_ptr->nh); - gw_sub_ptr->nh = NULL; - } - } else { + if (!sofia_private) { nua_handle_destroy(nh); } - + break; } + + end: + + if (gateway) { + sofia_reg_release_gateway(gateway); + } + } diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 821a086880..fe4f0c57b9 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -47,7 +47,7 @@ static void sofia_reg_new_handle(sofia_gateway_t *gateway_ptr, int attach) nua_handle_bind(gateway_ptr->nh, NULL); nua_handle_destroy(gateway_ptr->nh); gateway_ptr->nh = NULL; - sofia_private_free(gateway_ptr->sofia_private); + gateway_ptr->sofia_private = NULL; } gateway_ptr->nh = nua_handle(gateway_ptr->profile->nua, NULL, @@ -56,23 +56,24 @@ static void sofia_reg_new_handle(sofia_gateway_t *gateway_ptr, int attach) NUTAG_CALLSTATE_REF(ss_state), SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END()); if (attach) { if (!gateway_ptr->sofia_private) { - gateway_ptr->sofia_private = malloc(sizeof(*gateway_ptr->sofia_private)); + gateway_ptr->sofia_private = su_alloc(gateway_ptr->nh->nh_home, sizeof(*gateway_ptr->sofia_private)); switch_assert(gateway_ptr->sofia_private); } memset(gateway_ptr->sofia_private, 0, sizeof(*gateway_ptr->sofia_private)); - gateway_ptr->sofia_private->gateway = gateway_ptr; + switch_set_string(gateway_ptr->sofia_private->gateway_name, gateway_ptr->name); nua_handle_bind(gateway_ptr->nh, gateway_ptr->sofia_private); } } -static void sofia_reg_new_sub_handle(sofia_gateway_subscription_t *gw_sub_ptr, int attach) +static void sofia_reg_new_sub_handle(sofia_gateway_subscription_t *gw_sub_ptr) { sofia_gateway_t *gateway_ptr = gw_sub_ptr->gateway; char *user_via = NULL; char *register_host = sofia_glue_get_register_host(gateway_ptr->register_proxy); int ss_state = nua_callstate_authenticating; + /* check for NAT and place a Via header if necessary (hostname or non-local IP) */ if (register_host && sofia_glue_check_nat(gateway_ptr->profile, register_host)) { user_via = sofia_glue_create_external_via(NULL, gateway_ptr->profile, gateway_ptr->register_transport); @@ -82,7 +83,7 @@ static void sofia_reg_new_sub_handle(sofia_gateway_subscription_t *gw_sub_ptr, i nua_handle_bind(gw_sub_ptr->nh, NULL); nua_handle_destroy(gw_sub_ptr->nh); gw_sub_ptr->nh = NULL; - sofia_private_free(gateway_ptr->sofia_private); + gw_sub_ptr->sofia_private = NULL; } gw_sub_ptr->nh = nua_handle(gateway_ptr->profile->nua, NULL, @@ -90,16 +91,14 @@ static void sofia_reg_new_sub_handle(sofia_gateway_subscription_t *gw_sub_ptr, i TAG_IF(user_via, SIPTAG_VIA_STR(user_via)), SIPTAG_TO_STR(gateway_ptr->register_to), NUTAG_CALLSTATE_REF(ss_state), SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END()); - if (attach) { - if (!gateway_ptr->sofia_private) { - gateway_ptr->sofia_private = malloc(sizeof(*gateway_ptr->sofia_private)); - switch_assert(gateway_ptr->sofia_private); - } - memset(gateway_ptr->sofia_private, 0, sizeof(*gateway_ptr->sofia_private)); - - gateway_ptr->sofia_private->gateway = gateway_ptr; - nua_handle_bind(gw_sub_ptr->nh, gateway_ptr->sofia_private); + if (!gw_sub_ptr->sofia_private) { + gw_sub_ptr->sofia_private = su_alloc(gw_sub_ptr->nh->nh_home, sizeof(*gw_sub_ptr->sofia_private)); + switch_assert(gw_sub_ptr->sofia_private); } + memset(gw_sub_ptr->sofia_private, 0, sizeof(*gw_sub_ptr->sofia_private)); + + switch_set_string(gw_sub_ptr->sofia_private->gateway_name, gateway_ptr->name); + nua_handle_bind(gw_sub_ptr->nh, gw_sub_ptr->sofia_private); switch_safe_free(register_host); switch_safe_free(user_via); @@ -109,6 +108,8 @@ static void sofia_reg_kill_sub(sofia_gateway_subscription_t *gw_sub_ptr) { sofia_gateway_t *gateway_ptr = gw_sub_ptr->gateway; + gw_sub_ptr->sofia_private = NULL; + if (gw_sub_ptr->nh) { nua_handle_bind(gw_sub_ptr->nh, NULL); } @@ -141,6 +142,7 @@ static void sofia_reg_kill_reg(sofia_gateway_t *gateway_ptr) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Destroying registration handle for %s\n", gateway_ptr->name); } + gateway_ptr->sofia_private = NULL; nua_handle_bind(gateway_ptr->nh, NULL); nua_handle_destroy(gateway_ptr->nh); gateway_ptr->nh = NULL; @@ -175,20 +177,18 @@ void sofia_reg_unregister(sofia_profile_t *profile) nua_handle_bind(gateway_ptr->nh, NULL); } - if (gateway_ptr->sofia_private) { - sofia_private_free(gateway_ptr->sofia_private); - } - if (gateway_ptr->state == REG_STATE_REGED) { sofia_reg_kill_reg(gateway_ptr); } for (gw_sub_ptr = gateway_ptr->subscriptions; gw_sub_ptr; gw_sub_ptr = gw_sub_ptr->next) { + if (gw_sub_ptr->state == SUB_STATE_SUBED) { sofia_reg_kill_sub(gw_sub_ptr); } } + gateway_ptr->subscriptions = NULL; } switch_mutex_unlock(mod_sofia_globals.hash_mutex); } @@ -229,7 +229,7 @@ void sofia_sub_check_gateway(sofia_profile_t *profile, time_t now) break; case SUB_STATE_UNSUBED: - sofia_reg_new_sub_handle(gw_sub_ptr, 1); + sofia_reg_new_sub_handle(gw_sub_ptr); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "subscribing to [%s] on gateway [%s]\n", gw_sub_ptr->event, gateway_ptr->name); @@ -2184,17 +2184,27 @@ void sofia_reg_handle_sip_r_register(int status, sofia_dispatch_event_t *de, tagi_t tags[]) { + sofia_gateway_t *gateway = NULL; + + if (sofia_private && !zstr(sofia_private->gateway_name)) { + gateway = sofia_reg_find_gateway(sofia_private->gateway_name); + } + + if (status >= 500) { - if (sofia_private && sofia_private->gateway) { - nua_handle_destroy(sofia_private->gateway->nh); - sofia_private->gateway->nh = NULL; + if (sofia_private && gateway) { + nua_handle_bind(gateway->nh, NULL); + gateway->sofia_private = NULL; + nua_handle_destroy(gateway->nh); + gateway->nh = NULL; + } else { nua_handle_destroy(nh); } } - if (sofia_private && sofia_private->gateway) { - reg_state_t ostate = sofia_private->gateway->state; + if (sofia_private && gateway) { + reg_state_t ostate = gateway->state; switch (status) { case 200: if (sip && sip->sip_contact) { @@ -2206,7 +2216,7 @@ void sofia_reg_handle_sip_r_register(int status, for (; contact; contact = contact->m_next) { if ((full = sip_header_as_string(nh->nh_home, (void *) contact))) { - if (switch_stristr(sofia_private->gateway->register_contact, full)) { + if (switch_stristr(gateway->register_contact, full)) { break; } @@ -2223,37 +2233,42 @@ void sofia_reg_handle_sip_r_register(int status, new_expires = contact->m_expires; expi = (uint32_t) atoi(new_expires); - if (expi > 0 && expi != sofia_private->gateway->freq) { - //sofia_private->gateway->freq = expi; - //sofia_private->gateway->expires_str = switch_core_sprintf(sofia_private->gateway->pool, "%d", expi); + if (expi > 0 && expi != gateway->freq) { + //gateway->freq = expi; + //gateway->expires_str = switch_core_sprintf(gateway->pool, "%d", expi); if (expi > 60) { - sofia_private->gateway->expires = switch_epoch_time_now(NULL) + (expi - 15); + gateway->expires = switch_epoch_time_now(NULL) + (expi - 15); } else { - sofia_private->gateway->expires = switch_epoch_time_now(NULL) + (expi - 2); + gateway->expires = switch_epoch_time_now(NULL) + (expi - 2); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Changing expire time to %d by request of proxy %s\n", expi, sofia_private->gateway->register_proxy); + "Changing expire time to %d by request of proxy %s\n", expi, gateway->register_proxy); } } } - sofia_private->gateway->state = REG_STATE_REGISTER; + gateway->state = REG_STATE_REGISTER; break; case 100: break; default: - sofia_private->gateway->state = REG_STATE_FAILED; - sofia_private->gateway->failure_status = status; + gateway->state = REG_STATE_FAILED; + gateway->failure_status = status; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Registration Failed with status %s [%d]. failure #%d\n", - sofia_private->gateway->name, switch_str_nil(phrase), status, ++sofia_private->gateway->failures); + gateway->name, switch_str_nil(phrase), status, ++gateway->failures); break; } - if (ostate != sofia_private->gateway->state) { - sofia_reg_fire_custom_gateway_state_event(sofia_private->gateway, status, phrase); + if (ostate != gateway->state) { + sofia_reg_fire_custom_gateway_state_event(gateway, status, phrase); } } + + if (gateway) { + sofia_reg_release_gateway(gateway); + } + } void sofia_reg_handle_sip_r_challenge(int status, @@ -2282,8 +2297,12 @@ void sofia_reg_handle_sip_r_challenge(int status, sip_auth_password = switch_channel_get_variable(channel, "sip_auth_password"); } - if (sofia_private && *sofia_private->auth_gateway_name) { - gw_name = sofia_private->auth_gateway_name; + if (sofia_private) { + if (*sofia_private->auth_gateway_name) { + gw_name = sofia_private->auth_gateway_name; + } else if (*sofia_private->gateway_name) { + gw_name = sofia_private->gateway_name; + } } if (session) { @@ -2407,7 +2426,7 @@ void sofia_reg_handle_sip_r_challenge(int status, tl_gets(tags, NUTAG_CALLSTATE_REF(ss_state), SIPTAG_WWW_AUTHENTICATE_REF(authenticate), TAG_END()); nua_authenticate(nh, - TAG_IF(sofia_private && sofia_private->gateway, SIPTAG_EXPIRES_STR(gateway ? gateway->expires_str : "3600")), + TAG_IF(gateway, SIPTAG_EXPIRES_STR(gateway ? gateway->expires_str : "3600")), NUTAG_AUTH(authentication), TAG_END()); goto end; From 9ec1e86574bc2fe49ea19aca120b3c74270baa18 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 10 Dec 2013 14:16:08 -0500 Subject: [PATCH 186/656] rpmbuild: update version of flite, lame, and opus --- freeswitch.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freeswitch.spec b/freeswitch.spec index 37f66cdf53..b59bc0f4ed 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -115,8 +115,8 @@ Vendor: http://www.freeswitch.org/ ###################################################################################################################### Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2 Source1: http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz -Source2: http://files.freeswitch.org/downloads/libs/flite-1.5.1-current.tar.bz2 -Source3: http://files.freeswitch.org/downloads/libs/lame-3.97.tar.gz +Source2: http://files.freeswitch.org/downloads/libs/flite-1.5.4-current.tar.bz2 +Source3: http://files.freeswitch.org/downloads/libs/lame-3.98.4.tar.gz Source4: http://files.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz Source5: http://files.freeswitch.org/downloads/libs/mpg123-1.13.2.tar.gz #Source6: http://files.freeswitch.org/downloads/libs/openldap-2.4.11.tar.gz @@ -126,7 +126,7 @@ Source8: http://files.freeswitch.org/downloads/libs/sphinxbase-0.7.tar.gz Source9: http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz Source10: http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz Source11: http://files.freeswitch.org/downloads/libs/json-c-0.9.tar.gz -Source12: http://files.freeswitch.org/downloads/libs/opus-0.9.0.tar.gz +Source12: http://files.freeswitch.org/downloads/libs/opus-1.0.3.tar.gz Prefix: %{prefix} From f5b18c0fdd91c1e5690e11819fcf769124881806 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Fri, 13 Dec 2013 11:46:14 +0800 Subject: [PATCH 187/656] FS-5642 --resolve add back the ETIMEDOUT check, needed on Mac --- libs/sofia-sip/libsofia-sip-ua/tport/ws.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index 41df93fdcf..f5534d6175 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -290,7 +290,7 @@ int ws_handshake(wsh_t *wsh) ws_raw_write(wsh, respond, strlen(respond)); wsh->handshake = 1; - + return 0; err: @@ -809,7 +809,7 @@ int xp_errno(void) int xp_is_blocking(int errcode) { - return errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EINTR; + return errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EINTR || errcode == ETIMEDOUT; } #endif From 87751f9eafb418fd1730ced1c170e3560ce01296 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 13 Dec 2013 23:13:56 +0500 Subject: [PATCH 188/656] FS-5036 --resolve --- src/switch_event.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/switch_event.c b/src/switch_event.c index 48743a7c30..33584496d7 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1102,9 +1102,16 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc *header->value = '\0'; } + hv += strlen(header->value); for(j = 0; j < header->idx; j++) { - switch_snprintf(header->value + strlen(header->value), len - strlen(header->value), "%s%s", j == 0 ? "" : "|:", header->array[j]); + if (j > 0) { + memcpy(hv, "|:", 2); + hv += 2; + } + memcpy(hv, header->array[j], strlen(header->array[j])); + hv += strlen(header->array[j]); } + *hv = '\0'; } } else { From 0292a04c7c39c7c90c8824df3c4ffcd28ccd312a Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sun, 15 Dec 2013 11:44:30 +0800 Subject: [PATCH 189/656] debug all media type --- src/mod/applications/mod_commands/mod_commands.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 7956903c38..8640524149 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -3666,7 +3666,7 @@ SWITCH_STANDARD_API(uuid_video_refresh_function) } -#define DEBUG_MEDIA_SYNTAX " " +#define DEBUG_MEDIA_SYNTAX " " SWITCH_STANDARD_API(uuid_debug_media_function) { char *mycmd = NULL, *argv[3] = { 0 }; @@ -3690,7 +3690,18 @@ SWITCH_STANDARD_API(uuid_debug_media_function) msg.from = __FILE__; if ((lsession = switch_core_session_locate(argv[0]))) { + if (!strcasecmp(argv[1], "all")) { + msg.string_array_arg[0] = "both"; + } + + again: status = switch_core_session_receive_message(lsession, &msg); + + if (status == SWITCH_STATUS_SUCCESS && !strcasecmp(argv[1], "all") && !strcmp(msg.string_array_arg[0], "both")) { + msg.string_array_arg[0] = "vboth"; + goto again; + } + switch_core_session_rwunlock(lsession); } } From 14f7e1aa5803f43179f1d92a6bf74de3966d1ee3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 16 Dec 2013 11:54:15 -0500 Subject: [PATCH 190/656] FS-5920 --resolve --- libs/js/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/js/configure.ac b/libs/js/configure.ac index d13ed9cc06..98fdbe985b 100644 --- a/libs/js/configure.ac +++ b/libs/js/configure.ac @@ -35,7 +35,7 @@ AC_SUBST(JS_VERSION) CFLAGS="$CFLAGS $CONFIGURE_CFLAGS" CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS" -LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS" +LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS -lm" AC_CANONICAL_BUILD AC_CANONICAL_HOST From bc0859181283722501297ac26a4d260235738306 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 16 Dec 2013 22:55:50 +0500 Subject: [PATCH 191/656] update opus to 1.1 --- src/mod/codecs/mod_opus/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/codecs/mod_opus/Makefile b/src/mod/codecs/mod_opus/Makefile index 53ad7d5ffa..64183f1a78 100644 --- a/src/mod/codecs/mod_opus/Makefile +++ b/src/mod/codecs/mod_opus/Makefile @@ -1,6 +1,6 @@ BASE=../../../.. -OPUS=opus-1.0.3 +OPUS=opus-1.1 OPUS_DIR=$(switch_srcdir)/libs/$(OPUS) OPUS_BUILDDIR=$(switch_builddir)/libs/$(OPUS) From 8231cb9f01093a04176f3ed212252faf79c6cb57 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 16 Dec 2013 23:46:29 +0500 Subject: [PATCH 192/656] fix codec renegotiation on hold/reinvite issue --- src/switch_core_media.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index cc960c886d..7ffd10eed4 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2844,6 +2844,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } } + if (session->bugs) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "Session is connected to a media bug. " + "Re-Negotiation implicitly disabled.\n"); + reneg = 0; + } + if (!reneg && smh->num_negotiated_codecs) { codec_array = smh->negotiated_codecs; total_codecs = smh->num_negotiated_codecs; @@ -3278,7 +3285,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s match = 1; a_engine->codec_negotiated = 1; - + smh->num_negotiated_codecs = 0; + for(j = 0; j < m_idx; j++) { payload_map_t *pmap = switch_core_media_add_payload_map(session, SWITCH_MEDIA_TYPE_AUDIO, @@ -3329,7 +3337,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s pmap->rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp); pmap->agreed_pt = (switch_payload_t) mmap->rm_pt; - smh->num_negotiated_codecs = 0; smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp; pmap->recv_pt = (switch_payload_t)mmap->rm_pt; From f2f1c38fe45f37a87a3bf86bb24da9091526bf92 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 16 Dec 2013 21:13:34 +0000 Subject: [PATCH 193/656] Follow bump to opus lib version for debian packaging --- debian/util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/util.sh b/debian/util.sh index 94ef0e0791..a767f3ba4f 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -107,7 +107,7 @@ getlibs () { getlib http://files.freeswitch.org/downloads/libs/pocketsphinx-0.7.tar.gz getlib http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz getlib http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz - getlib http://files.freeswitch.org/downloads/libs/opus-1.0.2.tar.gz + getlib http://files.freeswitch.org/downloads/libs/opus-1.1.tar.gz getlib http://files.freeswitch.org/downloads/libs/openldap-2.4.19.tar.gz getlib http://download.zeromq.org/zeromq-2.1.9.tar.gz \ || getlib http://download.zeromq.org/historic/zeromq-2.1.9.tar.gz From 23534be6761d130dc30441397458a0272c9c0755 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Mon, 16 Dec 2013 16:41:13 -0600 Subject: [PATCH 194/656] bump opus rev for rpm builds Conflicts: freeswitch.spec --- freeswitch.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freeswitch.spec b/freeswitch.spec index b59bc0f4ed..c53ee53d14 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -126,7 +126,7 @@ Source8: http://files.freeswitch.org/downloads/libs/sphinxbase-0.7.tar.gz Source9: http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz Source10: http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz Source11: http://files.freeswitch.org/downloads/libs/json-c-0.9.tar.gz -Source12: http://files.freeswitch.org/downloads/libs/opus-1.0.3.tar.gz +Source12: http://files.freeswitch.org/downloads/libs/opus-1.1.tar.gz Prefix: %{prefix} From 24b7b48885ff91eecac06eb24169b90380e5a2f3 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 18 Dec 2013 00:55:29 +0500 Subject: [PATCH 195/656] FS-6042 FS-6044 --resolve --- src/include/switch_resample.h | 2 +- .../mod_conference/mod_conference.c | 156 ++++++++++++++---- src/switch_resample.c | 8 +- 3 files changed, 127 insertions(+), 39 deletions(-) diff --git a/src/include/switch_resample.h b/src/include/switch_resample.h index ee1de4e2c7..59fc0c68ec 100644 --- a/src/include/switch_resample.h +++ b/src/include/switch_resample.h @@ -39,7 +39,7 @@ */ #define switch_normalize_volume(x) if (x > 4) x = 4; if (x < -4) x = -4; -#define switch_normalize_volume_granular(x) if (x > 12) x = 12; if (x < -12) x = -12; +#define switch_normalize_volume_granular(x) if (x > 13) x = 13; if (x < -13) x = -13; #ifndef SWITCH_RESAMPLE_H #define SWITCH_RESAMPLE_H diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index cc3003b0cc..da2f6762ad 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -274,6 +274,7 @@ typedef struct conference_file_node { struct conference_file_node *next; char *file; switch_bool_t mux; + uint32_t member_id; } conference_file_node_t; typedef enum { @@ -2108,6 +2109,48 @@ static void conference_set_floor_holder(conference_obj_t *conference, conference } +static switch_status_t conference_file_close(conference_obj_t *conference, conference_file_node_t *node) +{ + switch_event_t *event; + conference_member_t *member = NULL; + + if (test_eflag(conference, EFLAG_PLAY_FILE_DONE) && + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { + + conference_add_event_data(conference, event); + + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "seconds", "%ld", (long) node->fh.samples_in / node->fh.native_rate); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "milliseconds", "%ld", (long) node->fh.samples_in / (node->fh.native_rate / 1000)); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "samples", "%ld", (long) node->fh.samples_in); + + if (node->fh.params) { + switch_event_merge(event, node->fh.params); + } + + if (node->member_id) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done"); + + if ((member = conference_member_get(conference, node->member_id))) { + conference_add_event_member_data(member, event); + switch_thread_rwlock_unlock(member->rwlock); + } + + } else { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done"); + } + + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", node->file); + + if (node->async) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true"); + } + + switch_event_fire(&event); + } + + return switch_core_file_close(&node->fh); +} + /* Gain exclusive access and remove the member from the list */ static switch_status_t conference_del_member(conference_obj_t *conference, conference_member_t *member) { @@ -2177,7 +2220,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe fnode = fnode->next; if (cur->type != NODE_TYPE_SPEECH) { - switch_core_file_close(&cur->fh); + conference_file_close(conference, cur); } pool = cur->pool; @@ -2662,18 +2705,12 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v } } else if (conference->fnode->type == NODE_TYPE_FILE) { switch_core_file_read(&conference->fnode->fh, file_frame, &file_sample_len); + if (conference->fnode->fh.vol) { + switch_change_sln_volume_granular((void *)file_frame, file_sample_len, conference->fnode->fh.vol); + } } if (file_sample_len <= 0) { - if (test_eflag(conference, EFLAG_PLAY_FILE_DONE) && - switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { - conference_add_event_data(conference, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", conference->fnode->file); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true"); - switch_event_fire(&event); - } - conference->fnode->done++; } else { has_file_data = 1; @@ -2690,14 +2727,6 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v switch_core_file_read(&conference->async_fnode->fh, async_file_frame, &file_sample_len); if (file_sample_len <= 0) { - if (test_eflag(conference, EFLAG_PLAY_FILE) && - switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { - conference_add_event_data(conference, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", conference->async_fnode->file); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", "true"); - switch_event_fire(&event); - } conference->async_fnode->done++; } else { if (has_file_data) { @@ -2852,7 +2881,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v if (conference->async_fnode && conference->async_fnode->done) { switch_memory_pool_t *pool; - switch_core_file_close(&conference->async_fnode->fh); + conference_file_close(conference, conference->async_fnode); pool = conference->async_fnode->pool; conference->async_fnode = NULL; switch_core_destroy_memory_pool(&pool); @@ -2863,7 +2892,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v switch_memory_pool_t *pool; if (conference->fnode->type != NODE_TYPE_SPEECH) { - switch_core_file_close(&conference->fnode->fh); + conference_file_close(conference, conference->fnode); } fnode = conference->fnode; @@ -2918,7 +2947,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v fnode = fnode->next; if (cur->type != NODE_TYPE_SPEECH) { - switch_core_file_close(&cur->fh); + conference_file_close(conference, cur); } pool = cur->pool; @@ -2929,7 +2958,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v if (conference->async_fnode) { switch_memory_pool_t *pool; - switch_core_file_close(&conference->async_fnode->fh); + conference_file_close(conference, conference->async_fnode); pool = conference->async_fnode->pool; conference->async_fnode = NULL; switch_core_destroy_memory_pool(&pool); @@ -3953,7 +3982,7 @@ static void member_add_file_data(conference_member_t *member, int16_t *data, swi switch_memory_pool_t *pool; if (member->fnode->type != NODE_TYPE_SPEECH) { - switch_core_file_close(&member->fnode->fh); + conference_file_close(member->conference, member->fnode); } fnode = member->fnode; @@ -3981,17 +4010,7 @@ static void member_add_file_data(conference_member_t *member, int16_t *data, swi } if (file_sample_len <= 0) { - switch_event_t *event; member->fnode->done++; - - if (test_eflag(member->conference, EFLAG_PLAY_FILE) && - switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { - conference_add_event_data(member->conference, event); - conference_add_event_member_data(member, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member-done"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", member->fnode->file); - switch_event_fire(&event); - } } else { /* there is file node data to mix into the frame */ int32_t i, sample; @@ -4814,6 +4833,14 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char * goto done; } + if (fnode->fh.params) { + const char *vol = switch_event_get_header(fnode->fh.params, "vol"); + + if (!zstr(vol)) { + fnode->fh.vol = atoi(vol); + } + } + fnode->pool = pool; fnode->async = async; fnode->file = switch_core_strdup(fnode->pool, file); @@ -4829,7 +4856,7 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char * if (nptr) { switch_memory_pool_t *tmppool; - switch_core_file_close(&nptr->fh); + conference_file_close(conference, nptr); tmppool = nptr->pool; switch_core_destroy_memory_pool(&tmppool); } @@ -4903,6 +4930,7 @@ static switch_status_t conference_member_play_file(conference_member_t *member, fnode->type = NODE_TYPE_FILE; fnode->leadin = leadin; fnode->mux = mux; + fnode->member_id = member->id; /* Open the file */ fnode->fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; @@ -6232,6 +6260,11 @@ static switch_status_t conf_api_sub_play(conference_obj_t *conference, switch_st if (test_eflag(conference, EFLAG_PLAY_FILE) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_add_event_data(conference, event); + + if (conference->fnode->fh.params) { + switch_event_merge(event, conference->fnode->fh.params); + } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", argv[2]); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Async", async ? "true" : "false"); @@ -6256,6 +6289,11 @@ static switch_status_t conf_api_sub_play(conference_obj_t *conference, switch_st if (test_eflag(conference, EFLAG_PLAY_FILE_MEMBER) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_add_event_member_data(member, event); + + if (member->fnode->fh.params) { + switch_event_merge(event, member->fnode->fh.params); + } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-member"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "File", argv[2]); switch_event_fire(&event); @@ -6897,6 +6935,54 @@ static switch_status_t conf_api_sub_recording(conference_obj_t *conference, swit } } +static switch_status_t conf_api_sub_file_vol(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) +{ + if (argc >= 1) { + conference_file_node_t *fnode; + int vol = 0; + int ok = 0; + + if (argc < 2) { + stream->write_function(stream, "missing args\n"); + return SWITCH_STATUS_GENERR; + } + + switch_mutex_lock(conference->mutex); + + fnode = conference->fnode; + + vol = atoi(argv[2]); + + if (argc > 3) { + if (strcasecmp(argv[3], "async")) { + fnode = conference->async_fnode; + } + } + + printf("WTF %p %p\n", (void *) conference, (void *) fnode); + + if (fnode && fnode->type == NODE_TYPE_FILE) { + fnode->fh.vol = vol; + ok = 1; + } + switch_mutex_unlock(conference->mutex); + + + if (ok) { + stream->write_function(stream, "volume changed\n"); + return SWITCH_STATUS_SUCCESS; + } else { + stream->write_function(stream, "File not playing\n"); + return SWITCH_STATUS_GENERR; + } + + + } else { + stream->write_function(stream, "Invalid parameters:\n"); + return SWITCH_STATUS_GENERR; + } +} + static switch_status_t conf_api_sub_pin(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv) { switch_assert(conference != NULL); @@ -7085,6 +7171,7 @@ static api_command_t conf_api_sub_commands[] = { {"nopin", (void_fn_t) & conf_api_sub_pin, CONF_API_SUB_ARGS_SPLIT, "nopin", ""}, {"get", (void_fn_t) & conf_api_sub_get, CONF_API_SUB_ARGS_SPLIT, "get", ""}, {"set", (void_fn_t) & conf_api_sub_set, CONF_API_SUB_ARGS_SPLIT, "set", " "}, + {"file-vol", (void_fn_t) & conf_api_sub_file_vol, CONF_API_SUB_ARGS_SPLIT, "file-vol", ""}, {"floor", (void_fn_t) & conf_api_sub_floor, CONF_API_SUB_MEMBER_TARGET, "floor", ""}, {"vid-floor", (void_fn_t) & conf_api_sub_vid_floor, CONF_API_SUB_MEMBER_TARGET, "vid-floor", " [force]"}, {"clear-vid-floor", (void_fn_t) & conf_api_sub_clear_vid_floor, CONF_API_SUB_ARGS_AS_ONE, "clear-vid-floor", ""} @@ -9772,7 +9859,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load) nl = strlen(conf_api_sub_commands[i].pcommand) + strlen(conf_api_sub_commands[i].psyntax) + 5; switch_snprintf(cmd_str, sizeof(cmd_str), "add conference ::conference::list_conferences %s", conf_api_sub_commands[i].pcommand); - switch_console_set_complete(cmd_str); if (p != NULL) { diff --git a/src/switch_resample.c b/src/switch_resample.c index 807d8fb18f..e245ad188e 100644 --- a/src/switch_resample.c +++ b/src/switch_resample.c @@ -289,8 +289,8 @@ SWITCH_DECLARE(void) switch_mux_channels(int16_t *data, switch_size_t samples, u SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t samples, int32_t vol) { double newrate = 0; - double pos[12] = {1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0}; - double neg[12] = {.917, .834, .751, .668, .585, .502, .419, .336, .253, .017, .087, .004}; + double pos[13] = {1.25, 1.50, 1.75, 2.0, 2.25, 2.50, 2.75, 3.0, 3.25, 3.50, 3.75, 4.0, 4.5}; + double neg[13] = {.917, .834, .751, .668, .585, .502, .419, .336, .253, .087, .017, .004, 0.0}; double *chart; uint32_t i; @@ -306,7 +306,7 @@ SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t s i = abs(vol) - 1; - switch_assert(i < 12); + switch_assert(i < 13); newrate = chart[i]; @@ -320,6 +320,8 @@ SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t s switch_normalize_to_16bit(tmp); fp[x] = (int16_t) tmp; } + } else { + memset(data, 0, samples * 2); } } From 635fbc4bd3769cd4468a5d871f2186b8aa991787 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 18 Dec 2013 03:19:33 +0500 Subject: [PATCH 196/656] add loops var durning looped execution --- src/switch_ivr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/switch_ivr.c b/src/switch_ivr.c index daba288c7e..d3124ca5ce 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -620,6 +620,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se switch_channel_set_variable(channel, "app_uuid", event_uuid); } + switch_channel_set_variable_printf(channel, "current_loop", "%d", x + 1); + switch_channel_set_variable_printf(channel, "total_loops", "%d", loops); if (switch_core_session_execute_application(session, app_name, app_arg) != SWITCH_STATUS_SUCCESS) { if (!inner || switch_channel_test_flag(channel, CF_STOP_BROADCAST)) switch_channel_clear_flag(channel, CF_BROADCAST); @@ -632,6 +634,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se } } + switch_channel_set_variable(channel, "current_loop", NULL); + switch_channel_set_variable(channel, "total_loops", NULL); + if (b_uuid) { if ((b_session = switch_core_session_locate(b_uuid))) { switch_channel_t *b_channel = switch_core_session_get_channel(b_session); From 713303a2a9584cd61e75c60cc9196454eba6ddcb Mon Sep 17 00:00:00 2001 From: Eliot Gable Date: Wed, 18 Dec 2013 16:19:58 +0000 Subject: [PATCH 197/656] Add case-insensitive search to switch_regex_match() based on code from switch_regex_perform(). --- src/switch_regex.c | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/switch_regex.c b/src/switch_regex.c index 2a98638134..f31b50afdf 100644 --- a/src/switch_regex.c +++ b/src/switch_regex.c @@ -79,6 +79,9 @@ SWITCH_DECLARE(int) switch_regex_perform(const char *field, const char *expressi if ((opts = strrchr(tmp, '/'))) { *opts++ = '\0'; } else { + /* Note our error */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Regular Expression Error expression[%s] missing ending '/' delimeter\n", expression); goto end; } expression = tmp; @@ -212,9 +215,35 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c int match_count = 0; /* Number of times the regex was matched */ int offset_vectors[255]; /* not used, but has to exist or pcre won't even try to find a match */ int pcre_flags = 0; + uint32_t flags = 0; + char *tmp = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; + + if (*expression == '/') { + char *opts = NULL; + tmp = strdup(expression + 1); + assert(tmp); + if ((opts = strrchr(tmp, '/'))) { + *opts++ = '\0'; + } else { + /* Note our error */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Regular Expression Error expression[%s] missing ending '/' delimeter\n", expression); + goto end; + } + expression = tmp; + if (opts) { + if (strchr(opts, 'i')) { + flags |= PCRE_CASELESS; + } + if (strchr(opts, 's')) { + flags |= PCRE_DOTALL; + } + } + } /* Compile the expression */ - pcre_prepared = pcre_compile(expression, 0, &error, &error_offset, NULL); + pcre_prepared = pcre_compile(expression, flags, &error, &error_offset, NULL); /* See if there was an error in the expression */ if (error != NULL) { @@ -228,7 +257,7 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c "Regular Expression Error expression[%s] error[%s] location[%d]\n", expression, error, error_offset); /* We definitely didn't match anything */ - return SWITCH_STATUS_FALSE; + goto end; } if (*partial) { @@ -250,14 +279,17 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, c /* Was it a match made in heaven? */ if (match_count > 0) { *partial = 0; - return SWITCH_STATUS_SUCCESS; + switch_goto_status(SWITCH_STATUS_SUCCESS, end); } else if (match_count == PCRE_ERROR_PARTIAL || match_count == PCRE_ERROR_BADPARTIAL) { /* yes it is already set, but the code is clearer this way */ *partial = 1; - return SWITCH_STATUS_SUCCESS; + switch_goto_status(SWITCH_STATUS_SUCCESS, end); } else { - return SWITCH_STATUS_FALSE; + goto end; } + end: + switch_safe_free(tmp); + return status; } SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const char *expression) From 9a20d0ab0c17cdd12d9279720ade804ce2fefe13 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 18 Dec 2013 23:22:13 +0500 Subject: [PATCH 198/656] FS-6054 --resolve --- src/switch_core_media.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 7ffd10eed4..7ecaa5123a 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3717,6 +3717,8 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session switch_channel_clear_flag(session->channel, CF_HOLD_LOCK); if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD)) { + const char *val; + switch_yield(250000); if (a_engine->max_missed_packets) { @@ -3735,6 +3737,13 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session } } + if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && + !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) && + !switch_channel_test_flag(session->channel, CF_WEBRTC)) { + /* Reactivate the NAT buster flag. */ + switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } + switch_channel_clear_flag(session->channel, CF_PROTO_HOLD); switch_channel_mark_hold(session->channel, SWITCH_FALSE); switch_channel_presence(session->channel, "unknown", "unhold", NULL); From 763bc8cfde6f36b939c5f67de2d5d9035b94a886 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 18 Dec 2013 18:53:19 +0000 Subject: [PATCH 199/656] Fix freeswitch-all module provides/replaces/conflicts We were generating freeswitch-mod-mod-* rather than freeswitch-mod-*. --- debian/bootstrap.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 8f12a9fc3f..3704b4b1a9 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -230,8 +230,8 @@ map_pkgs () { map_pkgs_langs () { $fsx "freeswitch-lang-${lang//_/-}"; } map_langs map_pkgs_langs map_pkgs_mods () { - $fsx "freeswitch-mod-${module//_/-}" - $fsx "freeswitch-mod-${module//_/-}-dbg"; } + $fsx "freeswitch-${module//_/-}" + $fsx "freeswitch-${module//_/-}-dbg"; } map_modules map_pkgs_mods } From 8d1c1a5bb9aa77f757659dec07f0c34a1379823b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 18 Dec 2013 19:51:12 +0000 Subject: [PATCH 200/656] Treat freeswitch-{sounds,music} as virtual packages only Previously we were creating freeswitch-music, freeswitch-sounds, freeswitch-sounds-en, and freeswitch-sounds-en-us metapackages and also providing those names as virtual packages from the freeswitch-{sounds,music} source packages. This is unnecessarily confusing and meant that freeswitch-all wasn't depending on any sounds in actuality as it was also providing freeswitch-sounds. --- debian/bootstrap.sh | 68 ++++++++------------------------------------- 1 file changed, 11 insertions(+), 57 deletions(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 3704b4b1a9..dbe0491ee4 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -68,10 +68,6 @@ freeswitch-init freeswitch-sysvinit freeswitch-systemd freeswitch-lang -freeswitch-music -freeswitch-sounds -freeswitch-sounds-en -freeswitch-sounds-en-us ) err () { @@ -358,8 +354,8 @@ Recommends: freeswitch-mod-commands (= \${binary:Version}), freeswitch-init (= \${binary:Version}), freeswitch-lang (= \${binary:Version}), - freeswitch-music (= \${binary:Version}), - freeswitch-sounds (= \${binary:Version}) + freeswitch-music, + freeswitch-sounds Suggests: Description: Cross-Platform Scalable Multi-Protocol Soft Switch $(debian_wrap "${fs_description}") @@ -392,8 +388,8 @@ Recommends: freeswitch-init (= \${binary:Version}), freeswitch-lang (= \${binary:Version}), freeswitch-meta-codecs (= \${binary:Version}), - freeswitch-music (= \${binary:Version}), - freeswitch-sounds (= \${binary:Version}) + freeswitch-music, + freeswitch-sounds Suggests: freeswitch-mod-cidlookup (= \${binary:Version}), freeswitch-mod-curl (= \${binary:Version}), @@ -447,8 +443,8 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), Recommends: freeswitch-init (= \${binary:Version}), freeswitch-lang (= \${binary:Version}), - freeswitch-music (= \${binary:Version}), - freeswitch-sounds (= \${binary:Version}), + freeswitch-music, + freeswitch-sounds, freeswitch-conf-vanilla (= \${binary:Version}), Suggests: freeswitch-mod-spidermonkey (= \${binary:Version}), @@ -465,8 +461,8 @@ Recommends: freeswitch-init (= \${binary:Version}), freeswitch-lang (= \${binary:Version}), freeswitch-meta-codecs (= \${binary:Version}), - freeswitch-music (= \${binary:Version}), - freeswitch-sounds (= \${binary:Version}), + freeswitch-music, + freeswitch-sounds, freeswitch-mod-abstraction (= \${binary:Version}), freeswitch-mod-avmd (= \${binary:Version}), freeswitch-mod-blacklist (= \${binary:Version}), @@ -551,8 +547,8 @@ Recommends: freeswitch-meta-conf (= \${binary:Version}), freeswitch-meta-lang (= \${binary:Version}), freeswitch-meta-mod-say (= \${binary:Version}), - freeswitch-music (= \${binary:Version}), - freeswitch-sounds (= \${binary:Version}), + freeswitch-music, + freeswitch-sounds, freeswitch-mod-abstraction (= \${binary:Version}), freeswitch-mod-avmd (= \${binary:Version}), freeswitch-mod-blacklist (= \${binary:Version}), @@ -834,48 +830,6 @@ Description: Language files for FreeSWITCH This is a metapackage which depends on the default language packages for FreeSWITCH. -## sounds - -Package: freeswitch-music -Architecture: all -Depends: \${misc:Depends}, - freeswitch-music-default (>= 1.0.8) -Description: Music on hold audio for FreeSWITCH - $(debian_wrap "${fs_description}") - . - This is a metapackage which depends on the default music on hold - packages for FreeSWITCH. - -Package: freeswitch-sounds -Architecture: all -Depends: \${misc:Depends}, - freeswitch-sounds-en (= \${binary:Version}) -Description: Sounds for FreeSWITCH - $(debian_wrap "${fs_description}") - . - This is a metapackage which depends on the default sound packages for - FreeSWITCH. - -Package: freeswitch-sounds-en -Architecture: all -Depends: \${misc:Depends}, - freeswitch-sounds-en-us (= \${binary:Version}) -Description: English sounds for FreeSWITCH - $(debian_wrap "${fs_description}") - . - This is a metapackage which depends on the default English sound - packages for FreeSWITCH. - -Package: freeswitch-sounds-en-us -Architecture: all -Depends: \${misc:Depends}, - freeswitch-sounds-en-us-callie (>= 1.0.18) -Description: US English sounds for FreeSWITCH - $(debian_wrap "${fs_description}") - . - This is a metapackage which depends on the default US/English sound - packages for FreeSWITCH. - EOF } @@ -998,7 +952,7 @@ print_lang_control () { Package: freeswitch-lang-${lang//_/-} Architecture: all Depends: \${misc:Depends} -Recommends: freeswitch-sounds-${lang} (= \${binary:Version}) +Recommends: freeswitch-sounds-${lang} Description: ${lang_name} language files for FreeSWITCH $(debian_wrap "${fs_description}") . From 417ef16de5ca4a0b15da6b9ea6f8fbabc741ae48 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 19 Dec 2013 21:32:37 +0500 Subject: [PATCH 201/656] FS-6054 --- src/switch_core_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 7ecaa5123a..56c8d72ad4 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3739,7 +3739,7 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) && - !switch_channel_test_flag(session->channel, CF_WEBRTC)) { + !switch_channel_test_flag(session->channel, CF_WEBRTC) && a_engine->rtp_session) { /* Reactivate the NAT buster flag. */ switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } From 0ab8cf0f7cd29958813eb8bef8c5eb20a8aa9452 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 19 Dec 2013 21:36:28 +0500 Subject: [PATCH 202/656] FS-6054 --- src/switch_core_media.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 56c8d72ad4..d77e430b83 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3739,9 +3739,16 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) && !((val = switch_channel_get_variable(session->channel, "disable_rtp_auto_adjust")) && switch_true(val)) && - !switch_channel_test_flag(session->channel, CF_WEBRTC) && a_engine->rtp_session) { + !switch_channel_test_flag(session->channel, CF_WEBRTC)) { /* Reactivate the NAT buster flag. */ - switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + + if (a_engine->rtp_session) { + switch_rtp_set_flag(a_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } + + if (v_engine->rtp_session) { + switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } } switch_channel_clear_flag(session->channel, CF_PROTO_HOLD); From fede96f35ba9ee5269a553f091ed4a1199fa6b5c Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 19 Dec 2013 12:10:59 -0500 Subject: [PATCH 203/656] rpmbuild: tweak to config-rayo.sh to play nice /w rpmbuilder.sh --- scripts/ci/config-rayo.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ci/config-rayo.sh b/scripts/ci/config-rayo.sh index c346f5e0ed..119e01ea96 100755 --- a/scripts/ci/config-rayo.sh +++ b/scripts/ci/config-rayo.sh @@ -15,8 +15,8 @@ rpmbuild --define "VERSION_NUMBER $1" \ --define "_srcrpmdir %{_topdir}" \ -ba freeswitch-config-rayo.spec -mkdir $src_repo/RPMS -mv $src_repo/rpmbuild/*/*.rpm $src_repo/RPMS/. +mkdir -p $src_repo/RPMS +mv $src_repo/rpmbuild/*/freeswitch-config-rayo*.rpm $src_repo/RPMS/. cat 1>&2 < Date: Fri, 20 Dec 2013 09:56:04 -0500 Subject: [PATCH 204/656] FS-6051 added some logging to help troubleshoot mod_rayo crash --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index a6b749a869..c650e66877 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -731,8 +731,9 @@ struct rayo_actor *rayo_actor_locate(const char *jid, const char *file, int line if (actor) { if (!actor->destroy) { actor->ref_count++; - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Locate %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Locate (jid) %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); } else { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Locate (jid) %s: already marked for destruction!\n", jid); actor = NULL; } } @@ -754,8 +755,9 @@ struct rayo_actor *rayo_actor_locate_by_id(const char *id, const char *file, int if (actor) { if (!actor->destroy) { actor->ref_count++; - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Locate %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Locate (id) %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); } else { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Locate (id) %s: already marked for destruction!\n", id); actor = NULL; } } @@ -780,7 +782,12 @@ void rayo_actor_destroy(struct rayo_actor *actor, const char *file, int line) } actor->destroy = 1; if (actor->ref_count <= 0) { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Destroying %s\n", RAYO_JID(actor)); + if (actor->ref_count < 0) { + /* too many unlocks detected! */ + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Destroying %s, ref_count = %i\n", RAYO_JID(actor), actor->ref_count); + } else { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Destroying %s\n", RAYO_JID(actor)); + } if (actor->cleanup_fn) { actor->cleanup_fn(actor); } @@ -813,7 +820,12 @@ void rayo_actor_unlock(struct rayo_actor *actor, const char *file, int line) if (actor) { switch_mutex_lock(globals.actors_mutex); actor->ref_count--; - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Unlock %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); + if (actor->ref_count < 0) { + /* too many unlocks detected! */ + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_WARNING, "Unlock %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); + } else { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "", line, "", SWITCH_LOG_DEBUG, "Unlock %s: ref count = %i\n", RAYO_JID(actor), actor->ref_count); + } if (actor->ref_count <= 0 && actor->destroy) { rayo_actor_destroy(actor, file, line); } From 8f73c4ef448af91ec507f99681798b5a8d7ebd7f Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Mon, 23 Dec 2013 07:34:34 -0500 Subject: [PATCH 205/656] FS-6062 --resolve --- .../applications/mod_callcenter/mod_callcenter.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 785d44bc5e..07449411f0 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -797,6 +797,7 @@ int cc_queue_count(const char *queue) cc_status_t cc_agent_add(const char *agent, const char *type) { + switch_event_t *event; cc_status_t result = CC_STATUS_SUCCESS; char *sql; @@ -818,6 +819,14 @@ cc_status_t cc_agent_add(const char *agent, const char *type) agent, type, cc_agent_status2str(CC_AGENT_STATUS_LOGGED_OUT), cc_agent_state2str(CC_AGENT_STATE_WAITING)); cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", agent); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Type", type); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-add"); + switch_event_fire(&event); + } + } else { result = CC_STATUS_AGENT_INVALID_TYPE; goto done; @@ -986,6 +995,13 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen switch_safe_free(sql); result = CC_STATUS_SUCCESS; + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", agent); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "agent-contact-change"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Contact", value); + switch_event_fire(&event); + } } else if (!strcasecmp(key, "ready_time")) { sql = switch_mprintf("UPDATE agents SET ready_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent); cc_execute_sql(NULL, sql, NULL); From 1af72288d15ef6773bd8bc04bb867dd532b2d256 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 23 Dec 2013 22:43:06 +0500 Subject: [PATCH 206/656] FS-6061 --resolve --- src/switch_cpp.cpp | 2 +- swig_common.i | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 27d6dc68b6..85fc978a6f 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -1306,7 +1306,7 @@ SWITCH_DECLARE(bool) email(char *to, char *from, char *headers, char *body, char return false; } -SWITCH_DECLARE(void) msleep(unsigned ms) +SWITCH_DECLARE(void) switch_msleep(unsigned ms) { switch_sleep(ms * 1000); return; diff --git a/swig_common.i b/swig_common.i index 617b97551a..d64642027a 100644 --- a/swig_common.i +++ b/swig_common.i @@ -1,2 +1,7 @@ %typemap(newfree) char * "free($1);"; %newobject getGlobalVariable; +%rename(msleep) switch_msleep; + + + + From b63bacf43ff9d8fa9275bd6e548290cac2fd11a8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 23 Dec 2013 22:43:48 +0500 Subject: [PATCH 207/656] FS-6061 swigall --- src/include/switch_cpp.h | 2 +- src/mod/languages/mod_java/switch_swig_wrap.cpp | 2 +- src/mod/languages/mod_lua/freeswitch.i | 2 ++ src/mod/languages/mod_lua/mod_lua_wrap.cpp | 6 +++--- src/mod/languages/mod_managed/freeswitch_wrap.cxx | 2 +- src/mod/languages/mod_perl/mod_perl_wrap.cpp | 2 +- src/mod/languages/mod_python/mod_python_wrap.cpp | 2 +- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h index 57d122b79b..5a372c3cdb 100644 --- a/src/include/switch_cpp.h +++ b/src/include/switch_cpp.h @@ -398,7 +398,7 @@ SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *bod SWITCH_DECLARE(void) console_log(char *level_str, char *msg); SWITCH_DECLARE(void) console_clean_log(char *msg); -SWITCH_DECLARE(void) msleep(unsigned ms); +SWITCH_DECLARE(void) switch_msleep(unsigned ms); /** \brief bridge the audio of session_b into session_a * diff --git a/src/mod/languages/mod_java/switch_swig_wrap.cpp b/src/mod/languages/mod_java/switch_swig_wrap.cpp index 76de068715..fee7726382 100644 --- a/src/mod/languages/mod_java/switch_swig_wrap.cpp +++ b/src/mod/languages/mod_java/switch_swig_wrap.cpp @@ -3169,7 +3169,7 @@ SWIGEXPORT void JNICALL Java_org_freeswitch_swig_freeswitchJNI_msleep(JNIEnv *je (void)jenv; (void)jcls; arg1 = (unsigned int)jarg1; - msleep(arg1); + switch_msleep(arg1); } diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index 6fca226001..e61cad315b 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -19,6 +19,8 @@ %} + + /* Lua function typemap */ %typemap(in, checkfn = "lua_isfunction") SWIGLUA_FN { $1.L = L; diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index b1ff6d3a55..21e22ed53d 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -6299,10 +6299,10 @@ static int _wrap_msleep(lua_State* L) { int SWIG_arg = -1; unsigned int arg1 ; - SWIG_check_num_args("msleep",1,1) - if(!lua_isnumber(L,1)) SWIG_fail_arg("msleep",1,"unsigned int"); + SWIG_check_num_args("switch_msleep",1,1) + if(!lua_isnumber(L,1)) SWIG_fail_arg("switch_msleep",1,"unsigned int"); arg1 = (unsigned int)lua_tonumber(L, 1); - msleep(arg1); + switch_msleep(arg1); SWIG_arg=0; return SWIG_arg; diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index ea1a306269..88d3c7abfb 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -43119,7 +43119,7 @@ SWIGEXPORT void SWIGSTDCALL CSharp_msleep(unsigned int jarg1) { unsigned int arg1 ; arg1 = (unsigned int)jarg1; - msleep(arg1); + switch_msleep(arg1); } diff --git a/src/mod/languages/mod_perl/mod_perl_wrap.cpp b/src/mod/languages/mod_perl/mod_perl_wrap.cpp index 0757fcd85c..a7c2a690bd 100644 --- a/src/mod/languages/mod_perl/mod_perl_wrap.cpp +++ b/src/mod/languages/mod_perl/mod_perl_wrap.cpp @@ -8195,7 +8195,7 @@ XS(_wrap_msleep) { SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "msleep" "', argument " "1"" of type '" "unsigned int""'"); } arg1 = static_cast< unsigned int >(val1); - msleep(arg1); + switch_msleep(arg1); XSRETURN(argvi); diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index b7379edb7d..979621bafe 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -8398,7 +8398,7 @@ SWIGINTERN PyObject *_wrap_msleep(PyObject *SWIGUNUSEDPARM(self), PyObject *args SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "msleep" "', argument " "1"" of type '" "unsigned int""'"); } arg1 = static_cast< unsigned int >(val1); - msleep(arg1); + switch_msleep(arg1); resultobj = SWIG_Py_Void(); return resultobj; fail: From 0de5e6fb93a359bb2280c99e07719dbbeae7bd8a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 23 Dec 2013 23:24:13 +0500 Subject: [PATCH 208/656] chage swig hack diff --- src/mod/languages/mod_python/hack.diff | 36 +++++++++----------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/mod/languages/mod_python/hack.diff b/src/mod/languages/mod_python/hack.diff index 593e01aa27..9e50d93ba1 100644 --- a/src/mod/languages/mod_python/hack.diff +++ b/src/mod/languages/mod_python/hack.diff @@ -1,28 +1,16 @@ -Index: mod_python_wrap.cpp -=================================================================== ---- mod_python_wrap.cpp (revision 16581) -+++ mod_python_wrap.cpp (working copy) -@@ -5555,7 +5555,9 @@ - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "EventConsumer_pop" "', argument " "2"" of type '" "int""'"); - } - arg2 = static_cast< int >(val2); -+ Py_BEGIN_ALLOW_THREADS; - result = (Event *)(arg1)->pop(arg2); -+ Py_END_ALLOW_THREADS; - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 ); - return resultobj; - fail: -@@ -5577,7 +5579,9 @@ - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "EventConsumer_pop" "', argument " "1"" of type '" "EventConsumer *""'"); +--- mod_python_wrap_patched.cpp 2013-12-23 23:19:43.308488527 +0500 ++++ mod_python_wrap.cpp 2013-12-23 23:19:37.572488834 +0500 +@@ -5585,7 +5585,9 @@ + } + arg3 = static_cast< int >(val3); } - arg1 = reinterpret_cast< EventConsumer * >(argp1); + Py_BEGIN_ALLOW_THREADS; - result = (Event *)(arg1)->pop(); + result = (Event *)(arg1)->pop(arg2,arg3); + Py_END_ALLOW_THREADS; resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 ); return resultobj; fail: -@@ -9560,20 +9564,20 @@ +@@ -8515,20 +8517,20 @@ } @@ -46,7 +34,7 @@ Index: mod_python_wrap.cpp PyObject *resultobj = 0; char *arg1 = (char *) 0 ; CoreSession *arg2 = (CoreSession *) 0 ; -@@ -9598,7 +9602,7 @@ +@@ -8553,7 +8555,7 @@ } arg2 = reinterpret_cast< CoreSession * >(argp2); result = (PYTHON::Session *)new PYTHON::Session(arg1,arg2); @@ -55,7 +43,7 @@ Index: mod_python_wrap.cpp if (alloc1 == SWIG_NEWOBJ) delete[] buf1; return resultobj; fail: -@@ -9607,7 +9611,7 @@ +@@ -8562,7 +8564,7 @@ } @@ -64,7 +52,7 @@ Index: mod_python_wrap.cpp PyObject *resultobj = 0; char *arg1 = (char *) 0 ; PYTHON::Session *result = 0 ; -@@ -9623,7 +9627,7 @@ +@@ -8578,7 +8580,7 @@ } arg1 = reinterpret_cast< char * >(buf1); result = (PYTHON::Session *)new PYTHON::Session(arg1); @@ -73,7 +61,7 @@ Index: mod_python_wrap.cpp if (alloc1 == SWIG_NEWOBJ) delete[] buf1; return resultobj; fail: -@@ -9632,7 +9636,7 @@ +@@ -8587,7 +8589,7 @@ } @@ -82,7 +70,7 @@ Index: mod_python_wrap.cpp PyObject *resultobj = 0; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; PYTHON::Session *result = 0 ; -@@ -9647,7 +9651,7 @@ +@@ -8602,7 +8604,7 @@ } arg1 = reinterpret_cast< switch_core_session_t * >(argp1); result = (PYTHON::Session *)new PYTHON::Session(arg1); From 615a4ec1cff0f2ae998dfa63dea79caa05ddbb09 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 23 Dec 2013 23:26:34 +0500 Subject: [PATCH 209/656] update python diff --- src/mod/languages/mod_python/mod_python_wrap.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/languages/mod_python/mod_python_wrap.cpp b/src/mod/languages/mod_python/mod_python_wrap.cpp index 979621bafe..8db6cc0c8f 100644 --- a/src/mod/languages/mod_python/mod_python_wrap.cpp +++ b/src/mod/languages/mod_python/mod_python_wrap.cpp @@ -5596,7 +5596,9 @@ SWIGINTERN PyObject *_wrap_EventConsumer_pop(PyObject *SWIGUNUSEDPARM(self), PyO } arg3 = static_cast< int >(val3); } + Py_BEGIN_ALLOW_THREADS; result = (Event *)(arg1)->pop(arg2,arg3); + Py_END_ALLOW_THREADS; resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 ); return resultobj; fail: From bc8f2ffeb37e2acd0696748dd504ae04e1b92dc4 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 23 Dec 2013 15:28:30 -0600 Subject: [PATCH 210/656] vs2010 reswig --- src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx index 6a444f6ec1..8014491d77 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.2010.cxx @@ -42152,7 +42152,7 @@ SWIGEXPORT void SWIGSTDCALL CSharp_msleep(unsigned int jarg1) { unsigned int arg1 ; arg1 = (unsigned int)jarg1; - msleep(arg1); + switch_msleep(arg1); } From 88545a7fe186e4eff2dc22e3ef946d14aa0eb5d5 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 23 Dec 2013 17:27:20 -0500 Subject: [PATCH 211/656] .gitignore --- libs/esl/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 libs/esl/.gitignore diff --git a/libs/esl/.gitignore b/libs/esl/.gitignore new file mode 100644 index 0000000000..8c6f167b4c --- /dev/null +++ b/libs/esl/.gitignore @@ -0,0 +1,3 @@ +eslmake.rules +testserver_fork + From 87e3d25515a16be80e6455d78c428b3d88e43aa0 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 24 Dec 2013 10:36:45 -0600 Subject: [PATCH 212/656] FS-6052 --resolve --- src/mod/say/mod_say_ru/mod_say_ru.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mod/say/mod_say_ru/mod_say_ru.c b/src/mod/say/mod_say_ru/mod_say_ru.c index 826daa747a..843bb8b216 100644 --- a/src/mod/say/mod_say_ru/mod_say_ru.c +++ b/src/mod/say/mod_say_ru/mod_say_ru.c @@ -223,6 +223,20 @@ static switch_status_t ru_say_general_count(switch_say_file_handle_t *sh, char * switch_status_t status; cases_t cases; //падеж say_gender_t gender; //тип произноŃения + char sbuf[128] = ""; + + if (say_args->method == SSM_ITERATED) { + if ((tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)-1))) { + char *p; + for (p = tosay; p && *p; p++) { + switch_say_file(sh, "digits/%c", *p); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + return SWITCH_STATUS_SUCCESS; + } switch (say_args->type) { case SST_MESSAGES: From 1fb555770e0f758c5a76e31f0561a4ce8d38e8d3 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 24 Dec 2013 10:40:32 -0600 Subject: [PATCH 213/656] FS-6052 line endings --- src/mod/say/mod_say_ru/mod_say_ru.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/mod/say/mod_say_ru/mod_say_ru.c b/src/mod/say/mod_say_ru/mod_say_ru.c index 843bb8b216..14b266f6c2 100644 --- a/src/mod/say/mod_say_ru/mod_say_ru.c +++ b/src/mod/say/mod_say_ru/mod_say_ru.c @@ -223,19 +223,19 @@ static switch_status_t ru_say_general_count(switch_say_file_handle_t *sh, char * switch_status_t status; cases_t cases; //падеж say_gender_t gender; //тип произноŃения - char sbuf[128] = ""; - - if (say_args->method == SSM_ITERATED) { - if ((tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)-1))) { - char *p; - for (p = tosay; p && *p; p++) { - switch_say_file(sh, "digits/%c", *p); - } - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); - return SWITCH_STATUS_GENERR; - } - return SWITCH_STATUS_SUCCESS; + char sbuf[128] = ""; + + if (say_args->method == SSM_ITERATED) { + if ((tosay = switch_strip_commas(tosay, sbuf, sizeof(sbuf)-1))) { + char *p; + for (p = tosay; p && *p; p++) { + switch_say_file(sh, "digits/%c", *p); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n"); + return SWITCH_STATUS_GENERR; + } + return SWITCH_STATUS_SUCCESS; } switch (say_args->type) { From f03e9fe8af867c7c8939a6e7120b468d77bbbf8b Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 24 Dec 2013 11:37:09 -0600 Subject: [PATCH 214/656] FS-5585 --resolve --- src/switch_core_sqldb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index c53fc75a40..05d27c6caf 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -347,7 +347,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_ } else if (!strncasecmp(dsn, "sqlite://", 9)) { type = SCDB_TYPE_CORE_DB; connection_options.core_db_options.db_path = (char *)(dsn + 9); - } else if ((!(i = strncasecmp(dsn, "odbc://", 7))) || strchr(dsn, ':')) { + } else if ((!(i = strncasecmp(dsn, "odbc://", 7))) || strchr(dsn+2, ':')) { type = SCDB_TYPE_ODBC; if (i) { From cb6c17a691203813fa9fa8cbe9321296513f7d2c Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 24 Dec 2013 11:49:23 -0600 Subject: [PATCH 215/656] Tired of this --- scripts/perl/f-off-friendly-scanner.pl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 scripts/perl/f-off-friendly-scanner.pl diff --git a/scripts/perl/f-off-friendly-scanner.pl b/scripts/perl/f-off-friendly-scanner.pl new file mode 100644 index 0000000000..48c0b75083 --- /dev/null +++ b/scripts/perl/f-off-friendly-scanner.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl +# Fsck Friendly Scanner +# +use Data::Dumper; +require ESL; +$| = 1; +my $c = new ESL::ESLconnection("localhost", "8021", "ClueCon"); +$c->events("plain", "CUSTOM sofia::register"); + +while ($c->connected()) { + my $event = $c->recvEvent(); + + my $user_agent = $event->getHeader('user-agent'); + my $network_ip = $event->getHeader('network-ip'); + + if ($user_agent =~ m/friendly-scanner/) { + system("/sbin/iptables -I INPUT -s $network_ip -j DROP"); + } +} From a27fe4c5a5084a5d80808bd0aa0a45c697fea897 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 26 Dec 2013 23:57:10 +0500 Subject: [PATCH 216/656] some null checks from coverity --- src/switch_ivr_play_say.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 47451c3ca6..74ed83efb8 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1084,7 +1084,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess arg_recursion_check_start(args); - if (!strcasecmp(read_impl.iananame, "l16")) { + if (!zstr(read_impl.iananame) && !strcasecmp(read_impl.iananame, "l16")) { l16++; } @@ -1997,7 +1997,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, switch_channel_set_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE, tb); - if ((p = strchr(valid_terminators, tb[0]))) { + if (!zstr(valid_terminators) && (p = strchr(valid_terminators, tb[0]))) { if (p >= (valid_terminators + 1) && (*(p - 1) == '+' || *(p - 1) == 'x')) { switch_snprintf(digit_buffer + strlen(digit_buffer), digit_buffer_length - strlen(digit_buffer), "%s", tb); if (*(p - 1) == 'x') { From de65c19c3c538ef178c279b9a1507938dbab7ace Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 28 Dec 2013 01:39:03 +0500 Subject: [PATCH 217/656] FS-6007 FS-5083 FS-4514 --resolve --- src/switch_rtp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index afd308b9c5..58c7c054c4 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5637,6 +5637,9 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (send_msg) { bytes = datalen; + + m = send_msg->header.m; + if (flags && *flags & SFF_RFC2833) { send_msg->header.pt = rtp_session->te; } From 910c66150862546ca90fbccca479c133d38df036 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 27 Dec 2013 14:52:52 -0600 Subject: [PATCH 218/656] fix trivial compiler warning for last commit --- src/switch_rtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 58c7c054c4..37865d2e9b 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5638,7 +5638,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (send_msg) { bytes = datalen; - m = send_msg->header.m; + m = (uint8_t) send_msg->header.m; if (flags && *flags & SFF_RFC2833) { send_msg->header.pt = rtp_session->te; From 2f3f0bca5d78b9152cb4da1d56582fdebfa099e9 Mon Sep 17 00:00:00 2001 From: Brian West Date: Fri, 27 Dec 2013 16:39:11 -0600 Subject: [PATCH 219/656] fix list_users to have all users on all profiles --- src/mod/applications/mod_commands/mod_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 8640524149..be2d36cb4f 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -284,7 +284,7 @@ static void dump_user(struct user_struct *us) } if(zstr(dname)) { - apip = switch_mprintf("%s",switch_xml_attr_soft(x_user_tag, "id")); + apip = switch_mprintf("*/%s",switch_xml_attr_soft(x_user_tag, "id")); } else { apip = switch_mprintf("%s@%s",switch_xml_attr_soft(x_user_tag, "id"), dname); } From d432e837c5b9812b11bc8142256d4e9624d8839c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 30 Dec 2013 23:36:24 +0500 Subject: [PATCH 220/656] FS-6035 try this --- .../applications/mod_spandsp/mod_spandsp_modem.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c index 7c43577427..64218c1b31 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_modem.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_modem.c @@ -1238,7 +1238,7 @@ static void *SWITCH_THREAD_FUNC modem_thread(switch_thread_t *thread, void *obj) DWORD readBytes; OVERLAPPED o; #endif - char buf[T31_TX_BUF_LEN], tmp[80]; + char buf[T31_TX_BUF_LEN]; switch_mutex_lock(globals.mutex); modem_init(modem, control_handler); @@ -1298,18 +1298,8 @@ static void *SWITCH_THREAD_FUNC modem_thread(switch_thread_t *thread, void *obj) #endif t31_at_rx(modem->t31_state, buf, r); - memset(tmp, 0, sizeof(tmp)); if (!strncasecmp(buf, "AT", 2)) { - int x; - - strncpy(tmp, buf, r); - for (x = 0; x < r; x++) { - if (tmp[x] == '\r' || tmp[x] == '\n') { - tmp[x] = '\0'; - } - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Command on %s [%s]\n", modem->devlink, tmp); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Command on %s [%s]\n", modem->devlink, buf); } } From 990d41b1218fa209c8f0f8105f3343a67ad1c876 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Mon, 30 Dec 2013 13:14:05 -0600 Subject: [PATCH 221/656] FS-5704 --resolve --- Freeswitch.2010.sln | 149 +++++++++ Freeswitch.2012.sln | 149 +++++++++ libs/win32/Download OPUS.2010.vcxproj | 78 +++++ libs/win32/Download OPUS.2012.vcxproj | 80 +++++ libs/win32/opus/opus.2010.vcxproj | 250 ++++++++++++++ libs/win32/opus/opus.2010.vcxproj.filters | 93 ++++++ libs/win32/opus/opus.2012.vcxproj | 254 ++++++++++++++ libs/win32/opus/opus.2012.vcxproj.filters | 93 ++++++ libs/win32/opus/opus.celt.2010.vcxproj | 252 ++++++++++++++ .../win32/opus/opus.celt.2010.vcxproj.filters | 147 ++++++++ libs/win32/opus/opus.celt.2012.vcxproj | 256 ++++++++++++++ .../win32/opus/opus.celt.2012.vcxproj.filters | 147 ++++++++ libs/win32/opus/opus.silk_common.2010.vcxproj | 307 +++++++++++++++++ .../opus.silk_common.2010.vcxproj.filters | 315 ++++++++++++++++++ libs/win32/opus/opus.silk_common.2012.vcxproj | 311 +++++++++++++++++ .../opus.silk_common.2012.vcxproj.filters | 315 ++++++++++++++++++ libs/win32/opus/opus.silk_fixed.2010.vcxproj | 193 +++++++++++ .../opus/opus.silk_fixed.2010.vcxproj.filters | 111 ++++++ libs/win32/opus/opus.silk_fixed.2012.vcxproj | 197 +++++++++++ .../opus/opus.silk_fixed.2012.vcxproj.filters | 111 ++++++ libs/win32/opus/opus.silk_float.2010.vcxproj | 245 ++++++++++++++ .../opus/opus.silk_float.2010.vcxproj.filters | 129 +++++++ libs/win32/opus/opus.silk_float.2012.vcxproj | 249 ++++++++++++++ .../opus/opus.silk_float.2012.vcxproj.filters | 129 +++++++ src/mod/codecs/mod_opus/mod_opus.2010.vcxproj | 152 +++++++++ src/mod/codecs/mod_opus/mod_opus.2012.vcxproj | 156 +++++++++ 26 files changed, 4868 insertions(+) create mode 100644 libs/win32/Download OPUS.2010.vcxproj create mode 100644 libs/win32/Download OPUS.2012.vcxproj create mode 100644 libs/win32/opus/opus.2010.vcxproj create mode 100644 libs/win32/opus/opus.2010.vcxproj.filters create mode 100644 libs/win32/opus/opus.2012.vcxproj create mode 100644 libs/win32/opus/opus.2012.vcxproj.filters create mode 100644 libs/win32/opus/opus.celt.2010.vcxproj create mode 100644 libs/win32/opus/opus.celt.2010.vcxproj.filters create mode 100644 libs/win32/opus/opus.celt.2012.vcxproj create mode 100644 libs/win32/opus/opus.celt.2012.vcxproj.filters create mode 100644 libs/win32/opus/opus.silk_common.2010.vcxproj create mode 100644 libs/win32/opus/opus.silk_common.2010.vcxproj.filters create mode 100644 libs/win32/opus/opus.silk_common.2012.vcxproj create mode 100644 libs/win32/opus/opus.silk_common.2012.vcxproj.filters create mode 100644 libs/win32/opus/opus.silk_fixed.2010.vcxproj create mode 100644 libs/win32/opus/opus.silk_fixed.2010.vcxproj.filters create mode 100644 libs/win32/opus/opus.silk_fixed.2012.vcxproj create mode 100644 libs/win32/opus/opus.silk_fixed.2012.vcxproj.filters create mode 100644 libs/win32/opus/opus.silk_float.2010.vcxproj create mode 100644 libs/win32/opus/opus.silk_float.2010.vcxproj.filters create mode 100644 libs/win32/opus/opus.silk_float.2012.vcxproj create mode 100644 libs/win32/opus/opus.silk_float.2012.vcxproj.filters create mode 100644 src/mod/codecs/mod_opus/mod_opus.2010.vcxproj create mode 100644 src/mod/codecs/mod_opus/mod_opus.2012.vcxproj diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln index 37ba5cfac0..a8f431c61e 100644 --- a/Freeswitch.2010.sln +++ b/Freeswitch.2010.sln @@ -572,6 +572,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcbt", "libs\win32\libcbt EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_cielab_luts", "libs\spandsp\src\msvc\make_cielab_luts.2010.vcxproj", "{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download OPUS", "libs\win32\Download OPUS.2010.vcxproj", "{092124C9-09ED-43C7-BD6D-4AE5D6B3C547}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "opus", "opus", "{ED2CA8B5-8E91-4296-A120-02BB0B674652}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "libs\win32\opus\opus.2010.vcxproj", "{FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.celt", "libs\win32\opus\opus.celt.2010.vcxproj", "{245603E3-F580-41A5-9632-B25FE3372CBF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.silk_common", "libs\win32\opus\opus.silk_common.2010.vcxproj", "{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.silk_fixed", "libs\win32\opus\opus.silk_fixed.2010.vcxproj", "{8484C90D-1561-402F-A91D-2DB10F8C5171}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.silk_float", "libs\win32\opus\opus.silk_float.2010.vcxproj", "{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_opus", "src\mod\codecs\mod_opus\mod_opus.2010.vcxproj", "{64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_t43_gray_code_tables", "libs\spandsp\src\msvc\make_t43_gray_code_tables.2010.vcxproj", "{EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}" EndProject Global @@ -3812,6 +3828,131 @@ Global {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x64.Build.0 = All|Win32 {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x64 Setup.ActiveCfg = All|Win32 {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x86 Setup.ActiveCfg = All|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|Win32.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|Win32.Build.0 = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|x64.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|x64 Setup.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|x86 Setup.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|Win32.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|Win32.Build.0 = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x64.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x64.Build.0 = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|Win32.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|Win32.Build.0 = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x64.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x64.Build.0 = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x64 Setup.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x86 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|Win32.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|Win32.Build.0 = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x64.ActiveCfg = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x64.Build.0 = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x64 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x86 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|Win32.ActiveCfg = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|Win32.Build.0 = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x64.ActiveCfg = Debug|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x64.Build.0 = Debug|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|Win32.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|Win32.Build.0 = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x64.ActiveCfg = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x64.Build.0 = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x64 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x86 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|Win32.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|Win32.Build.0 = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x64.ActiveCfg = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x64.Build.0 = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x64 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x86 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.Build.0 = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.ActiveCfg = Debug|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.Build.0 = Debug|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.Build.0 = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.ActiveCfg = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.Build.0 = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x86 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|Win32.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|Win32.Build.0 = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x64.ActiveCfg = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x64.Build.0 = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x64 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x86 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.ActiveCfg = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.Build.0 = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.ActiveCfg = Debug|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.Build.0 = Debug|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.Build.0 = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.ActiveCfg = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.Build.0 = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x86 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|Win32.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|Win32.Build.0 = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x64.ActiveCfg = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x64.Build.0 = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x64 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x86 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.ActiveCfg = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.Build.0 = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.ActiveCfg = Debug|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.Build.0 = Debug|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.Build.0 = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.ActiveCfg = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.Build.0 = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x86 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|Win32.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|Win32.Build.0 = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x64.ActiveCfg = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x64.Build.0 = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x64 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x86 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.ActiveCfg = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.Build.0 = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.ActiveCfg = Debug|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.Build.0 = Debug|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.Build.0 = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.ActiveCfg = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.Build.0 = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x86 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|Win32.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|Win32.Build.0 = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x64.ActiveCfg = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x64.Build.0 = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x64 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x86 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|Win32.ActiveCfg = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|Win32.Build.0 = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x64.ActiveCfg = Debug|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x64.Build.0 = Debug|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|Win32.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|Win32.Build.0 = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x64.ActiveCfg = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x64.Build.0 = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x64 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x86 Setup.ActiveCfg = Release|Win32 {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.All|Win32.ActiveCfg = All|Win32 {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.All|Win32.Build.0 = All|Win32 {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.All|x64.ActiveCfg = All|Win32 @@ -3845,6 +3986,7 @@ Global {D5C87B19-150D-4EF3-A671-96589BD2D14A} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {4D418176-3B33-47E6-A63E-01BA34ADD21C} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {AFA983D6-4569-4F88-BA94-555ED00FD9A8} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {5FD31A25-5D83-4794-8BEE-904DAD84CE71} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} {FFAA4C52-3A53-4F99-90C1-D59D1F0427F3} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} {0DF3ABD0-DDC0-4265-B778-07C66780979B} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} @@ -3946,6 +4088,7 @@ Global {9D04A840-CE18-4FF5-A6D3-0A2BB92FF2E6} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} + {ED2CA8B5-8E91-4296-A120-02BB0B674652} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {EC3E5C7F-EE09-47E2-80FE-546363D14A98} = {B8F5B47B-8568-46EB-B320-64C17D2A98BC} {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {0C808854-54D1-4230-BFF5-77B5FD905000} @@ -3986,6 +4129,7 @@ Global {B808178B-82F0-4CF4-A2B1-921939FA24D0} = {C120A020-773F-4EA3-923F-B67AF28B750D} {D578E676-7EC8-4548-BD8B-845C635F14AD} = {C120A020-773F-4EA3-923F-B67AF28B750D} {652AD5F7-8488-489F-AAD0-7FBE064703B6} = {C120A020-773F-4EA3-923F-B67AF28B750D} + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547} = {C120A020-773F-4EA3-923F-B67AF28B750D} {988CACF7-3FCB-4992-BE69-77872AE67DC8} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {5BC072DB-3826-48EA-AF34-FE32AA01E83B} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {FA429E98-8B03-45E6-A096-A4BC5E821DE4} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} @@ -4034,5 +4178,10 @@ Global {0D108721-EAE8-4BAF-8102-D8960EC93647} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} {CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} {B535402E-38D2-4D54-8360-423ACBD17192} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {245603E3-F580-41A5-9632-B25FE3372CBF} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {8484C90D-1561-402F-A91D-2DB10F8C5171} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} EndGlobalSection EndGlobal diff --git a/Freeswitch.2012.sln b/Freeswitch.2012.sln index be88964420..2d4ad4a9cc 100644 --- a/Freeswitch.2012.sln +++ b/Freeswitch.2012.sln @@ -577,6 +577,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcbt", "libs\win32\libcbt EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_cielab_luts", "libs\spandsp\src\msvc\make_cielab_luts.2012.vcxproj", "{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download OPUS", "libs\win32\Download OPUS.2012.vcxproj", "{092124C9-09ED-43C7-BD6D-4AE5D6B3C547}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "opus", "opus", "{ED2CA8B5-8E91-4296-A120-02BB0B674652}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "libs\win32\opus\opus.2012.vcxproj", "{FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.celt", "libs\win32\opus\opus.celt.2012.vcxproj", "{245603E3-F580-41A5-9632-B25FE3372CBF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.silk_common", "libs\win32\opus\opus.silk_common.2012.vcxproj", "{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.silk_fixed", "libs\win32\opus\opus.silk_fixed.2012.vcxproj", "{8484C90D-1561-402F-A91D-2DB10F8C5171}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus.silk_float", "libs\win32\opus\opus.silk_float.2012.vcxproj", "{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_opus", "src\mod\codecs\mod_opus\mod_opus.2012.vcxproj", "{64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_t43_gray_code_tables", "libs\spandsp\src\msvc\make_t43_gray_code_tables.2012.vcxproj", "{EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}" EndProject Global @@ -3822,6 +3838,131 @@ Global {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x64.Build.0 = All|Win32 {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x64 Setup.ActiveCfg = All|Win32 {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x86 Setup.ActiveCfg = All|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|Win32.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|Win32.Build.0 = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|x64.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|x64 Setup.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|x86 Setup.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|Win32.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|Win32.Build.0 = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x64.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x64.Build.0 = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|Win32.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|Win32.Build.0 = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x64.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x64.Build.0 = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x64 Setup.ActiveCfg = Release|Win32 + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.Release|x86 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|Win32.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|Win32.Build.0 = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x64.ActiveCfg = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x64.Build.0 = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x64 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.All|x86 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|Win32.ActiveCfg = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|Win32.Build.0 = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x64.ActiveCfg = Debug|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x64.Build.0 = Debug|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|Win32.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|Win32.Build.0 = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x64.ActiveCfg = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x64.Build.0 = Release|x64 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x64 Setup.ActiveCfg = Release|Win32 + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E}.Release|x86 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|Win32.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|Win32.Build.0 = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x64.ActiveCfg = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x64.Build.0 = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x64 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.All|x86 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.ActiveCfg = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.Build.0 = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.ActiveCfg = Debug|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.Build.0 = Debug|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.Build.0 = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.ActiveCfg = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.Build.0 = Release|x64 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64 Setup.ActiveCfg = Release|Win32 + {245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x86 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|Win32.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|Win32.Build.0 = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x64.ActiveCfg = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x64.Build.0 = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x64 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.All|x86 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.ActiveCfg = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.Build.0 = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.ActiveCfg = Debug|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.Build.0 = Debug|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.Build.0 = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.ActiveCfg = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.Build.0 = Release|x64 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64 Setup.ActiveCfg = Release|Win32 + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x86 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|Win32.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|Win32.Build.0 = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x64.ActiveCfg = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x64.Build.0 = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x64 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.All|x86 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.ActiveCfg = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.Build.0 = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.ActiveCfg = Debug|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.Build.0 = Debug|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.Build.0 = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.ActiveCfg = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.Build.0 = Release|x64 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64 Setup.ActiveCfg = Release|Win32 + {8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x86 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|Win32.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|Win32.Build.0 = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x64.ActiveCfg = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x64.Build.0 = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x64 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.All|x86 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.ActiveCfg = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.Build.0 = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.ActiveCfg = Debug|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.Build.0 = Debug|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.Build.0 = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.ActiveCfg = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.Build.0 = Release|x64 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64 Setup.ActiveCfg = Release|Win32 + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x86 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|Win32.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|Win32.Build.0 = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x64.ActiveCfg = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x64.Build.0 = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x64 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.All|x86 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|Win32.ActiveCfg = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|Win32.Build.0 = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x64.ActiveCfg = Debug|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x64.Build.0 = Debug|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x64 Setup.ActiveCfg = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Debug|x86 Setup.ActiveCfg = Debug|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|Win32.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|Win32.Build.0 = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x64.ActiveCfg = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x64.Build.0 = Release|x64 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x64 Setup.ActiveCfg = Release|Win32 + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB}.Release|x86 Setup.ActiveCfg = Release|Win32 {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.All|Win32.ActiveCfg = All|Win32 {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.All|Win32.Build.0 = All|Win32 {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5}.All|x64.ActiveCfg = All|Win32 @@ -3855,6 +3996,7 @@ Global {D5C87B19-150D-4EF3-A671-96589BD2D14A} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {4D418176-3B33-47E6-A63E-01BA34ADD21C} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {AFA983D6-4569-4F88-BA94-555ED00FD9A8} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB} = {F881ADA2-2F1A-4046-9FEB-191D9422D781} {5FD31A25-5D83-4794-8BEE-904DAD84CE71} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} {FFAA4C52-3A53-4F99-90C1-D59D1F0427F3} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} {0DF3ABD0-DDC0-4265-B778-07C66780979B} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C} @@ -3956,6 +4098,7 @@ Global {2386B892-35F5-46CF-A0F0-10394D2FBF9B} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {77BC1DD2-C9A1-44D7-BFFA-1320370CACB9} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {85F0CF8C-C7AB-48F6-BA19-CC94CF87F981} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} + {ED2CA8B5-8E91-4296-A120-02BB0B674652} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B} {EC3E5C7F-EE09-47E2-80FE-546363D14A98} = {B8F5B47B-8568-46EB-B320-64C17D2A98BC} {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {0C808854-54D1-4230-BFF5-77B5FD905000} @@ -3996,6 +4139,7 @@ Global {B808178B-82F0-4CF4-A2B1-921939FA24D0} = {C120A020-773F-4EA3-923F-B67AF28B750D} {D578E676-7EC8-4548-BD8B-845C635F14AD} = {C120A020-773F-4EA3-923F-B67AF28B750D} {652AD5F7-8488-489F-AAD0-7FBE064703B6} = {C120A020-773F-4EA3-923F-B67AF28B750D} + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547} = {C120A020-773F-4EA3-923F-B67AF28B750D} {988CACF7-3FCB-4992-BE69-77872AE67DC8} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {5BC072DB-3826-48EA-AF34-FE32AA01E83B} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} {FA429E98-8B03-45E6-A096-A4BC5E821DE4} = {6CD61A1D-797C-470A-BE08-8C31B68BB336} @@ -4044,5 +4188,10 @@ Global {0D108721-EAE8-4BAF-8102-D8960EC93647} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} {CEE544A9-0303-44C2-8ECE-EFA7D7BCBBBA} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} {B535402E-38D2-4D54-8360-423ACBD17192} = {9DE35039-A8F6-4FBF-B1B6-EB527F802411} + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {245603E3-F580-41A5-9632-B25FE3372CBF} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {8484C90D-1561-402F-A91D-2DB10F8C5171} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {ED2CA8B5-8E91-4296-A120-02BB0B674652} EndGlobalSection EndGlobal diff --git a/libs/win32/Download OPUS.2010.vcxproj b/libs/win32/Download OPUS.2010.vcxproj new file mode 100644 index 0000000000..36688eba3a --- /dev/null +++ b/libs/win32/Download OPUS.2010.vcxproj @@ -0,0 +1,78 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + Download OPUS + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547} + Download OPUS + Win32Proj + + + + Utility + MultiByte + + + Utility + MultiByte + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(PlatformName)\OPUS\$(Configuration)\ + $(PlatformName)\OPUS\$(Configuration)\ + + + + $(IntDir)BuildLog $(ProjectName).htm + + + + + + + + + $(IntDir)BuildLog $(ProjectName).htm + + + + + + + + + Document + Downloading OPUS. + if not exist "$(ProjectDir)..\opus-1.1" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/opus-1.1.tar.gz "$(ProjectDir).." + + $(ProjectDir)..\opus-1.1;%(Outputs) + Downloading OPUS. + if not exist "$(ProjectDir)..\opus-1.1" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/opus-1.1.tar.gz "$(ProjectDir).." + + $(ProjectDir)..\opus-1.1;%(Outputs) + + + + + + diff --git a/libs/win32/Download OPUS.2012.vcxproj b/libs/win32/Download OPUS.2012.vcxproj new file mode 100644 index 0000000000..42553ea7ee --- /dev/null +++ b/libs/win32/Download OPUS.2012.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + Download OPUS + {092124C9-09ED-43C7-BD6D-4AE5D6B3C547} + Download OPUS + Win32Proj + + + + Utility + MultiByte + v110 + + + Utility + MultiByte + v110 + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(PlatformName)\OPUS\$(Configuration)\ + $(PlatformName)\OPUS\$(Configuration)\ + + + + $(IntDir)BuildLog $(ProjectName).htm + + + + + + + + + $(IntDir)BuildLog $(ProjectName).htm + + + + + + + + + Document + Downloading OPUS. + if not exist "$(ProjectDir)..\opus-1.1" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/opus-1.1.tar.gz "$(ProjectDir).." + + $(ProjectDir)..\opus-1.1;%(Outputs) + Downloading OPUS. + if not exist "$(ProjectDir)..\opus-1.1" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/opus-1.1.tar.gz "$(ProjectDir).." + + $(ProjectDir)..\opus-1.1;%(Outputs) + + + + + + diff --git a/libs/win32/opus/opus.2010.vcxproj b/libs/win32/opus/opus.2010.vcxproj new file mode 100644 index 0000000000..7dc9cd19e4 --- /dev/null +++ b/libs/win32/opus/opus.2010.vcxproj @@ -0,0 +1,250 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + Win32Proj + opus + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E} + + + + StaticLibrary + true + + + StaticLibrary + true + + + false + StaticLibrary + true + + + StaticLibrary + false + + + + + + + + + + + + + + + + + + + true + opus + + + true + opus + + + false + opus + + + false + + + opus + + + + HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + + + MachineX86 + true + Console + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + + + true + Console + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + Level3 + ProgramDatabase + true + + + MachineX86 + false + Console + true + true + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + false + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + Level3 + ProgramDatabase + + + false + Console + true + true + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + false + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + false + false + false + false + false + + + {245603e3-f580-41a5-9632-b25fe3372cbf} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + {8484c90d-1561-402f-a91d-2db10f8c5171} + + + {9c4961d2-5ddb-40c7-9be8-ca918dc4e782} + + + + + + diff --git a/libs/win32/opus/opus.2010.vcxproj.filters b/libs/win32/opus/opus.2010.vcxproj.filters new file mode 100644 index 0000000000..80b78c2044 --- /dev/null +++ b/libs/win32/opus/opus.2010.vcxproj.filters @@ -0,0 +1,93 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/libs/win32/opus/opus.2012.vcxproj b/libs/win32/opus/opus.2012.vcxproj new file mode 100644 index 0000000000..ab8a0e1f29 --- /dev/null +++ b/libs/win32/opus/opus.2012.vcxproj @@ -0,0 +1,254 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + Win32Proj + opus + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E} + + + + StaticLibrary + true + v110 + + + StaticLibrary + true + v110 + + + false + StaticLibrary + true + v110 + + + StaticLibrary + false + v110 + + + + + + + + + + + + + + + + + + + true + opus + + + true + opus + + + false + opus + + + false + + + opus + + + + HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + + + MachineX86 + true + Console + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + + + true + Console + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + Level3 + ProgramDatabase + true + + + MachineX86 + false + Console + true + true + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + false + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\celt;..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + Level3 + ProgramDatabase + + + false + Console + true + true + celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories) + false + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + false + false + false + false + false + + + {245603e3-f580-41a5-9632-b25fe3372cbf} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + {8484c90d-1561-402f-a91d-2db10f8c5171} + + + {9c4961d2-5ddb-40c7-9be8-ca918dc4e782} + + + + + + diff --git a/libs/win32/opus/opus.2012.vcxproj.filters b/libs/win32/opus/opus.2012.vcxproj.filters new file mode 100644 index 0000000000..80b78c2044 --- /dev/null +++ b/libs/win32/opus/opus.2012.vcxproj.filters @@ -0,0 +1,93 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/libs/win32/opus/opus.celt.2010.vcxproj b/libs/win32/opus/opus.celt.2010.vcxproj new file mode 100644 index 0000000000..f722cb0a0d --- /dev/null +++ b/libs/win32/opus/opus.celt.2010.vcxproj @@ -0,0 +1,252 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {245603E3-F580-41A5-9632-B25FE3372CBF} + Win32Proj + opus.celt + opus.celt + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + + + + celt + + + + celt + + + + celt + + + celt + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + + + + diff --git a/libs/win32/opus/opus.celt.2010.vcxproj.filters b/libs/win32/opus/opus.celt.2010.vcxproj.filters new file mode 100644 index 0000000000..9cdc36139e --- /dev/null +++ b/libs/win32/opus/opus.celt.2010.vcxproj.filters @@ -0,0 +1,147 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + diff --git a/libs/win32/opus/opus.celt.2012.vcxproj b/libs/win32/opus/opus.celt.2012.vcxproj new file mode 100644 index 0000000000..4d4119e328 --- /dev/null +++ b/libs/win32/opus/opus.celt.2012.vcxproj @@ -0,0 +1,256 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {245603E3-F580-41A5-9632-B25FE3372CBF} + Win32Proj + opus.celt + opus.celt + + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + + + + + + + + + + + + + + + + + + + + celt + + + + celt + + + + celt + + + celt + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\win32;..\..\opus-1.1\include;%(AdditionalIncludeDirectories) + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + + + + diff --git a/libs/win32/opus/opus.celt.2012.vcxproj.filters b/libs/win32/opus/opus.celt.2012.vcxproj.filters new file mode 100644 index 0000000000..9cdc36139e --- /dev/null +++ b/libs/win32/opus/opus.celt.2012.vcxproj.filters @@ -0,0 +1,147 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + diff --git a/libs/win32/opus/opus.silk_common.2010.vcxproj b/libs/win32/opus/opus.silk_common.2010.vcxproj new file mode 100644 index 0000000000..6e17e5cdc7 --- /dev/null +++ b/libs/win32/opus/opus.silk_common.2010.vcxproj @@ -0,0 +1,307 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} + Win32Proj + src_common + opus.silk_common + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + silk_common + + + silk_common + + + silk_common + + + + + silk_common + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + Fast + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + Fast + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + + + + diff --git a/libs/win32/opus/opus.silk_common.2010.vcxproj.filters b/libs/win32/opus/opus.silk_common.2010.vcxproj.filters new file mode 100644 index 0000000000..000040c0ca --- /dev/null +++ b/libs/win32/opus/opus.silk_common.2010.vcxproj.filters @@ -0,0 +1,315 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/libs/win32/opus/opus.silk_common.2012.vcxproj b/libs/win32/opus/opus.silk_common.2012.vcxproj new file mode 100644 index 0000000000..9c4952bc5c --- /dev/null +++ b/libs/win32/opus/opus.silk_common.2012.vcxproj @@ -0,0 +1,311 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} + Win32Proj + src_common + opus.silk_common + + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + + + + + + + + + + + + + + + + + silk_common + + + silk_common + + + silk_common + + + + + silk_common + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + Fast + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\fixed;..\..\opus-1.1\silk\float;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + Fast + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + + + + diff --git a/libs/win32/opus/opus.silk_common.2012.vcxproj.filters b/libs/win32/opus/opus.silk_common.2012.vcxproj.filters new file mode 100644 index 0000000000..000040c0ca --- /dev/null +++ b/libs/win32/opus/opus.silk_common.2012.vcxproj.filters @@ -0,0 +1,315 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/libs/win32/opus/opus.silk_fixed.2010.vcxproj b/libs/win32/opus/opus.silk_fixed.2010.vcxproj new file mode 100644 index 0000000000..33a7f5a065 --- /dev/null +++ b/libs/win32/opus/opus.silk_fixed.2010.vcxproj @@ -0,0 +1,193 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {8484C90D-1561-402F-A91D-2DB10F8C5171} + Win32Proj + src_FIX + opus.silk_fixed + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + silk_fixed + + + silk_fixed + + + silk_fixed + + + silk_fixed + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + {9c4961d2-5ddb-40c7-9be8-ca918dc4e782} + + + + + + diff --git a/libs/win32/opus/opus.silk_fixed.2010.vcxproj.filters b/libs/win32/opus/opus.silk_fixed.2010.vcxproj.filters new file mode 100644 index 0000000000..d4c0785df5 --- /dev/null +++ b/libs/win32/opus/opus.silk_fixed.2010.vcxproj.filters @@ -0,0 +1,111 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/libs/win32/opus/opus.silk_fixed.2012.vcxproj b/libs/win32/opus/opus.silk_fixed.2012.vcxproj new file mode 100644 index 0000000000..3e6b7c001c --- /dev/null +++ b/libs/win32/opus/opus.silk_fixed.2012.vcxproj @@ -0,0 +1,197 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {8484C90D-1561-402F-A91D-2DB10F8C5171} + Win32Proj + src_FIX + opus.silk_fixed + + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + + + + + + + + + + + + + + + + + silk_fixed + + + silk_fixed + + + silk_fixed + + + silk_fixed + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk\;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + {9c4961d2-5ddb-40c7-9be8-ca918dc4e782} + + + + + + diff --git a/libs/win32/opus/opus.silk_fixed.2012.vcxproj.filters b/libs/win32/opus/opus.silk_fixed.2012.vcxproj.filters new file mode 100644 index 0000000000..d4c0785df5 --- /dev/null +++ b/libs/win32/opus/opus.silk_fixed.2012.vcxproj.filters @@ -0,0 +1,111 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/libs/win32/opus/opus.silk_float.2010.vcxproj b/libs/win32/opus/opus.silk_float.2010.vcxproj new file mode 100644 index 0000000000..85be5aad3e --- /dev/null +++ b/libs/win32/opus/opus.silk_float.2010.vcxproj @@ -0,0 +1,245 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} + Win32Proj + src_FLP + opus.silk_float + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + silk_float + + + silk_float + + + silk_float + + + Compile + silk_float + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + + + + diff --git a/libs/win32/opus/opus.silk_float.2010.vcxproj.filters b/libs/win32/opus/opus.silk_float.2010.vcxproj.filters new file mode 100644 index 0000000000..4e132e1222 --- /dev/null +++ b/libs/win32/opus/opus.silk_float.2010.vcxproj.filters @@ -0,0 +1,129 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/libs/win32/opus/opus.silk_float.2012.vcxproj b/libs/win32/opus/opus.silk_float.2012.vcxproj new file mode 100644 index 0000000000..fce1b4cae5 --- /dev/null +++ b/libs/win32/opus/opus.silk_float.2012.vcxproj @@ -0,0 +1,249 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} + Win32Proj + src_FLP + opus.silk_float + + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + StaticLibrary + false + true + Unicode + v110 + + + + + + + + + + + + + + + + + + + silk_float + + + silk_float + + + silk_float + + + Compile + silk_float + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + Level3 + Disabled + HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDebugDLL + + + Windows + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + true + true + HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + Level3 + + + MaxSpeed + true + true + HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\opus-1.1\silk;..\..\opus-1.1\silk\fixed;..\..\opus-1.1\win32;..\..\opus-1.1\celt;..\..\opus-1.1\include + MultiThreadedDLL + + + Windows + true + true + true + + + "$(ProjectDir)..\..\opus-1.1\win32\genversion.bat" "$(ProjectDir)..\..\opus-1.1\win32\version.h" OPUS_VERSION + Generating version.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {092124c9-09ed-43c7-bd6d-4ae5d6b3c547} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + + + + diff --git a/libs/win32/opus/opus.silk_float.2012.vcxproj.filters b/libs/win32/opus/opus.silk_float.2012.vcxproj.filters new file mode 100644 index 0000000000..4e132e1222 --- /dev/null +++ b/libs/win32/opus/opus.silk_float.2012.vcxproj.filters @@ -0,0 +1,129 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/src/mod/codecs/mod_opus/mod_opus.2010.vcxproj b/src/mod/codecs/mod_opus/mod_opus.2010.vcxproj new file mode 100644 index 0000000000..412d5c4cbf --- /dev/null +++ b/src/mod/codecs/mod_opus/mod_opus.2010.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB} + mod_opus + Win32Proj + mod_opus + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + + + + + X64 + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + MachineX64 + + + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + + + + + X64 + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + MachineX64 + + + + + + + + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E} + true + false + false + true + false + + + {245603e3-f580-41a5-9632-b25fe3372cbf} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + {9c4961d2-5ddb-40c7-9be8-ca918dc4e782} + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + + + + diff --git a/src/mod/codecs/mod_opus/mod_opus.2012.vcxproj b/src/mod/codecs/mod_opus/mod_opus.2012.vcxproj new file mode 100644 index 0000000000..7921694c6b --- /dev/null +++ b/src/mod/codecs/mod_opus/mod_opus.2012.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {64E99CCA-3C6F-4AEB-9FA3-CFAC711257BB} + mod_opus + Win32Proj + mod_opus + + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + + + + + X64 + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + MachineX64 + + + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + + + + + X64 + + + ..\..\..\..\libs\opus-1.1\include;%(AdditionalIncludeDirectories) + + + + + false + + + MachineX64 + + + + + + + + {FD60942F-72D6-4CA1-8B57-EA1D1B95A89E} + true + false + false + true + false + + + {245603e3-f580-41a5-9632-b25fe3372cbf} + + + {c303d2fc-ff97-49b8-9ddd-467b4c9a0b16} + + + {9c4961d2-5ddb-40c7-9be8-ca918dc4e782} + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + + + + From e71dabae5001804913303da770a43572d879f424 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 31 Dec 2013 00:21:45 +0500 Subject: [PATCH 222/656] FS-6007 --- src/include/switch_types.h | 1 + src/switch_rtp.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index cf6f4c247d..ced44eb05e 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -634,6 +634,7 @@ typedef enum { */ typedef enum { SWITCH_RTP_FLAG_NOBLOCK = 0, + SWITCH_RTP_FLAG_DTMF_ON, SWITCH_RTP_FLAG_IO, SWITCH_RTP_FLAG_USE_TIMER, SWITCH_RTP_FLAG_RTCP_PASSTHRU, diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 37865d2e9b..0819b658cb 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -478,6 +478,15 @@ static void do_2833(switch_rtp_t *rtp_session); static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_size_t bytes, int *do_cng) { + if (rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON]) { + rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON]++; + + if (rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON] > 1000) { + rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON] = 0; + } + } + + #ifdef DEBUG_2833 if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d %ld\n", rtp_session->dtmf_data.in_digit_sanity, bytes); @@ -496,8 +505,9 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ we put up with as much as we can so we don't have to deal with being punished for doing it right. Nice guys finish last! */ + if (bytes > rtp_header_len && !rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] && - !rtp_session->flags[SWITCH_RTP_FLAG_PASS_RFC2833] && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { switch_size_t len = bytes - rtp_header_len; unsigned char *packet = (unsigned char *) RTP_BODY(rtp_session); int end; @@ -528,6 +538,17 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ in_digit_seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); ts = htonl(rtp_session->recv_msg.header.ts); + if (rtp_session->flags[SWITCH_RTP_FLAG_PASS_RFC2833]) { + + if (end) { + rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON] = 998; + } else if (!rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON]) { + rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON] = 1; + } + + return RESULT_CONTINUE; + } + if (in_digit_seq < rtp_session->dtmf_data.in_digit_seq) { if (rtp_session->dtmf_data.in_digit_seq - in_digit_seq > 100) { rtp_session->dtmf_data.in_digit_seq = 0; @@ -4031,7 +4052,8 @@ static void do_flush(switch_rtp_t *rtp_session, int force) if (!force) { if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] || - rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] + rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] || + rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON] ) { return; } From 153f66d739f45b1ad4871d6fa90c137e3de537f5 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Tue, 31 Dec 2013 16:45:44 -0600 Subject: [PATCH 223/656] add freetdm vs2012 build support --- libs/freetdm/freetdm.2012.sln | 127 ++++++++++ .../mod_freetdm/mod_freetdm.2012.vcxproj | 221 +++++++++++++++++ .../mod_freetdm.2012.vcxproj.filters | 14 ++ libs/freetdm/msvc/freetdm.2012.vcxproj | 230 ++++++++++++++++++ .../freetdm/msvc/freetdm.2012.vcxproj.filters | 137 +++++++++++ .../msvc/testanalog/testanalog.2012.vcxproj | 217 +++++++++++++++++ .../testanalog.2012.vcxproj.filters | 14 ++ .../msvc/testisdn/testisdn.2012.vcxproj | 217 +++++++++++++++++ .../testisdn/testisdn.2012.vcxproj.filters | 14 ++ .../ftmod_analog/ftmod_analog.2012.vcxproj | 202 +++++++++++++++ .../ftmod_analog.2012.vcxproj.filters | 23 ++ .../ftmod_analog_em.2012.vcxproj | 202 +++++++++++++++ .../ftmod_analog_em.2012.vcxproj.filters | 23 ++ .../ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj | 227 +++++++++++++++++ .../ftmod_isdn.2012.vcxproj.filters | 110 +++++++++ .../ftmod/ftmod_pika/ftmod_pika.2012.vcxproj | 202 +++++++++++++++ .../ftmod_pika.2012.vcxproj.filters | 23 ++ .../src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj | 163 +++++++++++++ .../ftmod_r2/ftmod_r2.2012.vcxproj.filters | 22 ++ .../ftmod_sangoma_isdn.2010.vcxproj | 6 +- .../ftmod_sangoma_isdn.2012.vcxproj | 207 ++++++++++++++++ .../ftmod_sangoma_isdn.2012.vcxproj.filters | 60 +++++ .../ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj | 205 ++++++++++++++++ .../ftmod_wanpipe.2012.vcxproj.filters | 18 ++ 24 files changed, 2883 insertions(+), 1 deletion(-) create mode 100644 libs/freetdm/freetdm.2012.sln create mode 100644 libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj create mode 100644 libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj.filters create mode 100644 libs/freetdm/msvc/freetdm.2012.vcxproj create mode 100644 libs/freetdm/msvc/freetdm.2012.vcxproj.filters create mode 100644 libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj create mode 100644 libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj.filters create mode 100644 libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj create mode 100644 libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj.filters create mode 100644 libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj create mode 100644 libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj.filters create mode 100644 libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj create mode 100644 libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj.filters create mode 100644 libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj create mode 100644 libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj.filters create mode 100644 libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj create mode 100644 libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj.filters create mode 100644 libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj create mode 100644 libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj.filters create mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj create mode 100644 libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj.filters create mode 100644 libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj create mode 100644 libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj.filters diff --git a/libs/freetdm/freetdm.2012.sln b/libs/freetdm/freetdm.2012.sln new file mode 100644 index 0000000000..1d4c335a8d --- /dev/null +++ b/libs/freetdm/freetdm.2012.sln @@ -0,0 +1,127 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetdm", "msvc\freetdm.2012.vcxproj", "{93B8812C-3EC4-4F78-8970-FFBFC99E167D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testanalog", "msvc\testanalog\testanalog.2012.vcxproj", "{BB833648-BAFF-4BE2-94DB-F8BB043C588C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testisdn", "msvc\testisdn\testisdn.2012.vcxproj", "{6DA6FD42-641D-4147-92F5-3BC4AAA6589B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_freetdm", "mod_freetdm\mod_freetdm.2012.vcxproj", "{FE3540C5-3303-46E0-A69E-D92F775687F1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog", "src\ftmod\ftmod_analog\ftmod_analog.2012.vcxproj", "{37C94798-6E33-4B4F-8EE0-C72A7DC91157}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_analog_em", "src\ftmod\ftmod_analog_em\ftmod_analog_em.2012.vcxproj", "{B3F49375-2834-4937-9D8C-4AC2EC911010}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_isdn", "src\ftmod\ftmod_isdn\ftmod_isdn.2012.vcxproj", "{729344A5-D5E9-434D-8EE8-AF8C6C795D15}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_pika", "src\ftmod\ftmod_pika\ftmod_pika.2012.vcxproj", "{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_wanpipe", "src\ftmod\ftmod_wanpipe\ftmod_wanpipe.2012.vcxproj", "{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_sangoma_isdn", "src\ftmod\ftmod_sangoma_isdn\ftmod_sangoma_isdn.2012.vcxproj", "{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_r2", "src\ftmod\ftmod_r2\ftmod_r2.2012.vcxproj", "{08C3EA27-A51D-47F8-B47D-B189C649CF30}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.ActiveCfg = Debug|Win32 + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|Win32.Build.0 = Debug|Win32 + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.ActiveCfg = Debug|x64 + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Debug|x64.Build.0 = Debug|x64 + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.ActiveCfg = Release|Win32 + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|Win32.Build.0 = Release|Win32 + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.ActiveCfg = Release|x64 + {93B8812C-3EC4-4F78-8970-FFBFC99E167D}.Release|x64.Build.0 = Release|x64 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.ActiveCfg = Debug|Win32 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|Win32.Build.0 = Debug|Win32 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.ActiveCfg = Debug|x64 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Debug|x64.Build.0 = Debug|x64 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.ActiveCfg = Release|Win32 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|Win32.Build.0 = Release|Win32 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.ActiveCfg = Release|x64 + {BB833648-BAFF-4BE2-94DB-F8BB043C588C}.Release|x64.Build.0 = Release|x64 + {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|Win32.ActiveCfg = Debug|Win32 + {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Debug|x64.ActiveCfg = Debug|x64 + {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|Win32.ActiveCfg = Release|Win32 + {6DA6FD42-641D-4147-92F5-3BC4AAA6589B}.Release|x64.ActiveCfg = Release|x64 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|Win32.Build.0 = Debug|Win32 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.ActiveCfg = Debug|x64 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Debug|x64.Build.0 = Debug|x64 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.ActiveCfg = Release|Win32 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|Win32.Build.0 = Release|Win32 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.ActiveCfg = Release|x64 + {FE3540C5-3303-46E0-A69E-D92F775687F1}.Release|x64.Build.0 = Release|x64 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.ActiveCfg = Debug|Win32 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|Win32.Build.0 = Debug|Win32 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.ActiveCfg = Debug|x64 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Debug|x64.Build.0 = Debug|x64 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.ActiveCfg = Release|Win32 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|Win32.Build.0 = Release|Win32 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.ActiveCfg = Release|x64 + {37C94798-6E33-4B4F-8EE0-C72A7DC91157}.Release|x64.Build.0 = Release|x64 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.ActiveCfg = Debug|Win32 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|Win32.Build.0 = Debug|Win32 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.ActiveCfg = Debug|x64 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Debug|x64.Build.0 = Debug|x64 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.ActiveCfg = Release|Win32 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|Win32.Build.0 = Release|Win32 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.ActiveCfg = Release|x64 + {B3F49375-2834-4937-9D8C-4AC2EC911010}.Release|x64.Build.0 = Release|x64 + {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|Win32.ActiveCfg = Debug|Win32 + {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Debug|x64.ActiveCfg = Debug|x64 + {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|Win32.ActiveCfg = Release|Win32 + {729344A5-D5E9-434D-8EE8-AF8C6C795D15}.Release|x64.ActiveCfg = Release|x64 + {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|Win32.ActiveCfg = Debug|Win32 + {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Debug|x64.ActiveCfg = Debug|x64 + {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|Win32.ActiveCfg = Release|Win32 + {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|x64.ActiveCfg = Release|x64 + {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.ActiveCfg = Debug|Win32 + {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.Build.0 = Debug|Win32 + {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|x64.ActiveCfg = Debug|x64 + {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32 + {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|x64.ActiveCfg = Release|x64 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.ActiveCfg = Debug|Win32 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|Win32.Build.0 = Debug|Win32 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.ActiveCfg = Debug|x64 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Debug|x64.Build.0 = Debug|x64 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.ActiveCfg = Release|Win32 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|Win32.Build.0 = Release|Win32 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.ActiveCfg = Release|x64 + {D021EF2A-460D-4827-A0F7-41FDECF46F1B}.Release|x64.Build.0 = Release|x64 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|Win32.Build.0 = Debug|Win32 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.ActiveCfg = Debug|x64 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Debug|x64.Build.0 = Debug|x64 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.ActiveCfg = Release|Win32 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|Win32.Build.0 = Release|Win32 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.ActiveCfg = Release|x64 + {2B1BAF36-0241-43E7-B865-A8338AD48E2E}.Release|x64.Build.0 = Release|x64 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|Win32.Build.0 = Debug|Win32 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.ActiveCfg = Debug|x64 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Debug|x64.Build.0 = Debug|x64 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.ActiveCfg = Release|Win32 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.Build.0 = Release|Win32 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64 + {0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64 + {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32 + {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|x64 + {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32 + {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|x64 + {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|Win32.ActiveCfg = Debug|Win32 + {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Debug|x64.ActiveCfg = Debug|x64 + {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|Win32.ActiveCfg = Release|Win32 + {08C3EA27-A51D-47F8-B47D-B189C649CF30}.Release|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj b/libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj new file mode 100644 index 0000000000..c89130912f --- /dev/null +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj @@ -0,0 +1,221 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_freetdm + {FE3540C5-3303-46E0-A69E-D92F775687F1} + mod_freetdm + Win32Proj + + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(PlatformName)\$(Configuration)\mod\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + false + + + $(OutDir)mod_freetdm.lib + MachineX86 + + + + + ../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + true + true + UseLinkTimeCodeGeneration + false + + + $(OutDir)mod_freetdm.lib + MachineX86 + + + + + X64 + + + Disabled + ../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + false + + + $(OutDir)mod_freetdm.lib + MachineX64 + + + + + X64 + + + ../../../src/include;../src/include;../../curl/include;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + + + FreeSwitchCore.lib;%(AdditionalDependencies) + ../../../$(PlatformName)\$(Configuration);%(AdditionalLibraryDirectories) + true + $(OutDir)$(TargetName).pdb + Windows + true + true + UseLinkTimeCodeGeneration + false + + + $(OutDir)mod_freetdm.lib + MachineX64 + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj.filters b/libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj.filters new file mode 100644 index 0000000000..92ac5ead47 --- /dev/null +++ b/libs/freetdm/mod_freetdm/mod_freetdm.2012.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/libs/freetdm/msvc/freetdm.2012.vcxproj b/libs/freetdm/msvc/freetdm.2012.vcxproj new file mode 100644 index 0000000000..e07a5ce072 --- /dev/null +++ b/libs/freetdm/msvc/freetdm.2012.vcxproj @@ -0,0 +1,230 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + freetdm + {93B8812C-3EC4-4F78-8970-FFBFC99E167D} + freetdm + Win32Proj + + + + DynamicLibrary + MultiByte + true + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + true + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + $(IntDir)BuildLog-freetdm.htm + + + Disabled + ../src/include;../src/include/private;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FREETDM_EXPORTS;TELETONE_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + false + false + + + Level4 + true + ProgramDatabase + CompileAsC + + + true + + + + + $(IntDir)BuildLog-freetdm.htm + + + ../src/include;../src/include/private;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FREETDM_EXPORTS;TELETONE_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions) + MultiThreadedDLL + false + false + + + Level4 + true + ProgramDatabase + CompileAsC + + + + + $(IntDir)BuildLog-freetdm.htm + + + X64 + + + Disabled + ../src/include;../src/include/private;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FREETDM_EXPORTS;TELETONE_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + false + false + + + Level4 + true + ProgramDatabase + CompileAsC + + + true + MachineX64 + + + + + $(IntDir)BuildLog-freetdm.htm + + + X64 + + + ../src/include;../src/include/private;../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;FREETDM_EXPORTS;TELETONE_EXPORTS;_WIN32_WINNT=0x0502;%(PreprocessorDefinitions) + MultiThreadedDLL + false + false + + + Level4 + true + ProgramDatabase + CompileAsC + + + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libs/freetdm/msvc/freetdm.2012.vcxproj.filters b/libs/freetdm/msvc/freetdm.2012.vcxproj.filters new file mode 100644 index 0000000000..9f15c9c737 --- /dev/null +++ b/libs/freetdm/msvc/freetdm.2012.vcxproj.filters @@ -0,0 +1,137 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + diff --git a/libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj b/libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj new file mode 100644 index 0000000000..5276eafa7b --- /dev/null +++ b/libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj @@ -0,0 +1,217 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + testanalog + {BB833648-BAFF-4BE2-94DB-F8BB043C588C} + testanalog + Win32Proj + + + + Application + Unicode + true + v110 + + + Application + Unicode + v110 + + + Application + Unicode + true + v110 + + + Application + Unicode + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + $(IntDir)BuildLog-testanalog.htm + + + Disabled + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + EditAndContinue + 4100;%(DisableSpecificWarnings) + + + true + Console + false + + + MachineX86 + + + + + $(IntDir)BuildLog-testanalog.htm + + + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Console + true + true + false + + + MachineX86 + + + + + $(IntDir)BuildLog-testanalog.htm + + + X64 + + + Disabled + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Console + false + + + MachineX64 + + + + + $(IntDir)BuildLog-testanalog.htm + + + X64 + + + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Console + true + true + false + + + MachineX64 + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj.filters b/libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj.filters new file mode 100644 index 0000000000..7ac3635cc5 --- /dev/null +++ b/libs/freetdm/msvc/testanalog/testanalog.2012.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj b/libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj new file mode 100644 index 0000000000..61f4759f1b --- /dev/null +++ b/libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj @@ -0,0 +1,217 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + testisdn + {6DA6FD42-641D-4147-92F5-3BC4AAA6589B} + testisdn + Win32Proj + + + + Application + Unicode + true + v110 + + + Application + Unicode + v110 + + + Application + Unicode + true + v110 + + + Application + Unicode + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + $(IntDir)BuildLog-testisdn.htm + + + Disabled + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + EditAndContinue + 4100;%(DisableSpecificWarnings) + + + true + Console + false + + + MachineX86 + + + + + $(IntDir)BuildLog-testisdn.htm + + + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Console + true + true + false + + + MachineX86 + + + + + $(IntDir)BuildLog-testisdn.htm + + + X64 + + + Disabled + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Console + false + + + MachineX64 + + + + + $(IntDir)BuildLog-testisdn.htm + + + X64 + + + ../../src/include;../../src/isdn/include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Console + true + true + false + + + MachineX64 + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj.filters b/libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj.filters new file mode 100644 index 0000000000..9d48828d4a --- /dev/null +++ b/libs/freetdm/msvc/testisdn/testisdn.2012.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj new file mode 100644 index 0000000000..03589c2300 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj @@ -0,0 +1,202 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ftmod_analog + {37C94798-6E33-4B4F-8EE0-C72A7DC91157} + ftmod_analog + Win32Proj + + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + EditAndContinue + 4100;%(DisableSpecificWarnings) + + + true + Windows + MachineX86 + + + + + MaxSpeed + true + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Windows + true + true + MachineX86 + + + + + X64 + + + Disabled + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + false + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Windows + MachineX64 + + + + + X64 + + + MaxSpeed + true + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level4 + false + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Windows + true + true + MachineX64 + + + + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj.filters new file mode 100644 index 0000000000..b6fed5927a --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.2012.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj new file mode 100644 index 0000000000..14c0021092 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj @@ -0,0 +1,202 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ftmod_analog_em + {B3F49375-2834-4937-9D8C-4AC2EC911010} + ftmod_analog_em + Win32Proj + + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + EditAndContinue + 4100;%(DisableSpecificWarnings) + + + true + Windows + MachineX86 + + + + + MaxSpeed + true + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level4 + true + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Windows + true + true + MachineX86 + + + + + X64 + + + Disabled + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + false + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Windows + MachineX64 + + + + + X64 + + + MaxSpeed + true + ..\..\include;..\..\isdn\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ANALOG_EM_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level4 + false + ProgramDatabase + 4100;%(DisableSpecificWarnings) + + + true + Windows + true + true + MachineX64 + + + + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj.filters new file mode 100644 index 0000000000..3326f9fd16 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.2012.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj new file mode 100644 index 0000000000..cf2344c4ec --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj @@ -0,0 +1,227 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ftmod_isdn + {729344A5-D5E9-434D-8EE8-AF8C6C795D15} + ftmod_isdn + Win32Proj + + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\isdn\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ISDN_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + EditAndContinue + + + true + Windows + MachineX86 + + + + + MaxSpeed + true + ..\..\isdn\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ISDN_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level4 + true + ProgramDatabase + + + true + Windows + true + true + MachineX86 + + + + + X64 + + + Disabled + ..\..\isdn\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_ISDN_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + true + ProgramDatabase + + + true + Windows + MachineX64 + + + + + X64 + + + MaxSpeed + true + ..\..\isdn\include;..\..\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_ISDN_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level4 + true + ProgramDatabase + + + true + Windows + true + true + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj.filters new file mode 100644 index 0000000000..30824888fc --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_isdn/ftmod_isdn.2012.vcxproj.filters @@ -0,0 +1,110 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj b/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj new file mode 100644 index 0000000000..c17deb8795 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj @@ -0,0 +1,202 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ftmod_pika + {E886B4D5-AB4F-4092-B8F4-3B06E1E462EF} + ftmod_pika + Win32Proj + + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + DynamicLibrary + Unicode + true + v110 + + + DynamicLibrary + Unicode + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\isdn\include;..\..\include;..\..\..\pika\aoh\inc;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_PIKA_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + pikahmpapi.lib;%(AdditionalDependencies) + ..\..\..\pika\aoh\lib;%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + + + MaxSpeed + true + ..\..\isdn\include;..\..\include;..\..\..\pika\aoh\inc;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_PIKA_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + pikahmpapi.lib;%(AdditionalDependencies) + ..\..\..\pika\aoh\lib;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX86 + + + + + X64 + + + Disabled + ..\..\isdn\include;..\..\include;..\..\..\pika\aoh\inc;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_PIKA_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + pikahmpapi.lib;%(AdditionalDependencies) + ..\..\..\pika\aoh\lib;%(AdditionalLibraryDirectories) + true + Windows + MachineX64 + + + + + X64 + + + MaxSpeed + true + ..\..\isdn\include;..\..\include;..\..\..\pika\aoh\inc;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_PIKA_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + pikahmpapi.lib;%(AdditionalDependencies) + ..\..\..\pika\aoh\lib;%(AdditionalLibraryDirectories) + true + Windows + true + true + MachineX64 + + + + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj.filters new file mode 100644 index 0000000000..4d4cec4668 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_pika/ftmod_pika.2012.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj new file mode 100644 index 0000000000..b95d13a02f --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj @@ -0,0 +1,163 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ftmod_r2 + {08C3EA27-A51D-47F8-B47D-B189C649CF30} + Win32Proj + + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + true + true + true + true + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + Disabled + ..\..\include;c:\Program Files\openr2\include\openr2;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + freetdm.lib;openr2.lib;%(AdditionalDependencies) + C:\Program Files\openr2\lib;$(OutDir);%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + + + Disabled + ..\..\include;c:\Program Files\openr2\include\openr2;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + freetdm.lib;openr2.lib;%(AdditionalDependencies) + C:\Program Files\openr2\lib;$(OutDir);%(AdditionalLibraryDirectories) + true + Windows + + + + + ..\..\include;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Windows + true + true + MachineX86 + + + + + ..\..\include;C:\Program Files\openr2\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;FTMOD_R2_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + true + Windows + true + true + + + + + + + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj.filters new file mode 100644 index 0000000000..9c91228e09 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_r2/ftmod_r2.2012.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj index 7ec8fd3346..102e7efe92 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj @@ -28,16 +28,20 @@ DynamicLibrary true + v110 DynamicLibrary true + v110 DynamicLibrary + v110 DynamicLibrary + v110 @@ -200,4 +204,4 @@ - + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj new file mode 100644 index 0000000000..102e7efe92 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj @@ -0,0 +1,207 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ftmod_sangoma_isdn + {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395} + ftmod_sangoma_isdn + Win32Proj + + + + DynamicLibrary + true + v110 + + + DynamicLibrary + true + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Configuration)\ + true + true + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + + + + Disabled + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + EnableFastChecks + + + Level3 + EditAndContinue + MultiThreadedDebugDLL + + + freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) + true + Console + false + + + MachineX86 + + + + + Disabled + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + EnableFastChecks + + + Level3 + ProgramDatabase + MultiThreadedDebugDLL + + + freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\libsng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) + true + Console + false + + + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDLL + + + Level3 + ProgramDatabase + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + Disabled + + + true + Windows + true + true + MachineX86 + freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\sangoma\sng_isdn\lib;C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDLL + + + Level3 + ProgramDatabase + C:\Program Files\sangoma\sng_isdn\include;../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + + + true + Windows + true + true + freetdm.lib;libsng_isdn.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj.filters new file mode 100644 index 0000000000..b3f44b428c --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2012.vcxproj.filters @@ -0,0 +1,60 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj new file mode 100644 index 0000000000..c91e4dc92a --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj @@ -0,0 +1,205 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + ftmod_wanpipe + {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD} + ftmod_wanpipe + Win32Proj + + + + DynamicLibrary + MultiByte + true + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + true + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + EditAndContinue + + + libsangoma.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) + true + Console + false + + + MachineX86 + + + + + X64 + + + Disabled + ../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + ProgramDatabase + + + libsangoma.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories) + true + Console + false + + + MachineX64 + + + + + ../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + libsangoma.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\Sangoma\api\lib\x86;%(AdditionalLibraryDirectories) + true + Console + true + true + false + + + MachineX86 + + + + + X64 + + + ../../include;C:\Program Files\Sangoma\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + + + Level3 + ProgramDatabase + + + libsangoma.lib;%(AdditionalDependencies) + $(OutDir);C:\Program Files\Sangoma\api\lib\x64;%(AdditionalLibraryDirectories) + true + Console + true + true + false + + + MachineX64 + + + + + + + + {93b8812c-3ec4-4f78-8970-ffbfc99e167d} + false + + + + + + \ No newline at end of file diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj.filters b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj.filters new file mode 100644 index 0000000000..15a8bc3d35 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.2012.vcxproj.filters @@ -0,0 +1,18 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + \ No newline at end of file From e75497c98d7b01b1b1666ee52ae6cbc3475e35e1 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Wed, 1 Jan 2014 12:08:40 -0600 Subject: [PATCH 224/656] revert accidental change in last commit for freetdm sang isdn --- .../ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj index 102e7efe92..7ec8fd3346 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2010.vcxproj @@ -28,20 +28,16 @@ DynamicLibrary true - v110 DynamicLibrary true - v110 DynamicLibrary - v110 DynamicLibrary - v110 @@ -204,4 +200,4 @@ - \ No newline at end of file + From 7ebb663ce6b8936ab05acc9439f4e34111f5b6aa Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 2 Jan 2014 17:51:09 -0600 Subject: [PATCH 225/656] FS-5401 --resolve whitespace only --- src/mod/applications/mod_avmd/mod_avmd.c | 614 +++++++++++------------ 1 file changed, 307 insertions(+), 307 deletions(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 68c72755fc..dffa78cd73 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -98,28 +98,28 @@ SWITCH_STANDARD_APP(avmd_start_function); /*! Status of the beep detection */ typedef enum { - BEEP_DETECTED, - BEEP_NOTDETECTED + BEEP_DETECTED, + BEEP_NOTDETECTED } avmd_beep_state_t; /*! Data related to the current status of the beep */ typedef struct { - avmd_beep_state_t beep_state; - size_t last_beep; + avmd_beep_state_t beep_state; + size_t last_beep; } avmd_state_t; /*! Type that holds session information pertinent to the avmd module. */ typedef struct { - /*! Internal FreeSWITCH session. */ - switch_core_session_t *session; - uint32_t rate; - circ_buffer_t b; - sma_buffer_t sma_b; - sma_buffer_t sqa_b; - size_t pos; - double f; - /* freq_table_t ft; */ - avmd_state_t state; + /*! Internal FreeSWITCH session. */ + switch_core_session_t *session; + uint32_t rate; + circ_buffer_t b; + sma_buffer_t sma_b; + sma_buffer_t sqa_b; + size_t pos; + double f; + /* freq_table_t ft; */ + avmd_state_t state; } avmd_session_t; static void avmd_process(avmd_session_t *session, switch_frame_t *frame); @@ -135,26 +135,26 @@ static void init_avmd_session_data(avmd_session_t *avmd_session, switch_core_se static void init_avmd_session_data(avmd_session_t *avmd_session, switch_core_session_t *fs_session) { /*! This is a worst case sample rate estimate */ - avmd_session->rate = 48000; - INIT_CIRC_BUFFER(&avmd_session->b, BEEP_LEN(avmd_session->rate), FRAME_LEN(avmd_session->rate), fs_session); + avmd_session->rate = 48000; + INIT_CIRC_BUFFER(&avmd_session->b, BEEP_LEN(avmd_session->rate), FRAME_LEN(avmd_session->rate), fs_session); - avmd_session->session = fs_session; - avmd_session->pos = 0; - avmd_session->f = 0.0; - avmd_session->state.last_beep = 0; - avmd_session->state.beep_state = BEEP_NOTDETECTED; + avmd_session->session = fs_session; + avmd_session->pos = 0; + avmd_session->f = 0.0; + avmd_session->state.last_beep = 0; + avmd_session->state.beep_state = BEEP_NOTDETECTED; - INIT_SMA_BUFFER( - &avmd_session->sma_b, - BEEP_LEN(avmd_session->rate) / SINE_LEN(avmd_session->rate), - fs_session - ); + INIT_SMA_BUFFER( + &avmd_session->sma_b, + BEEP_LEN(avmd_session->rate) / SINE_LEN(avmd_session->rate), + fs_session + ); - INIT_SMA_BUFFER( - &avmd_session->sqa_b, - BEEP_LEN(avmd_session->rate) / SINE_LEN(avmd_session->rate), - fs_session - ); + INIT_SMA_BUFFER( + &avmd_session->sqa_b, + BEEP_LEN(avmd_session->rate) / SINE_LEN(avmd_session->rate), + fs_session + ); } @@ -168,42 +168,42 @@ static void init_avmd_session_data(avmd_session_t *avmd_session, switch_core_se */ static switch_bool_t avmd_callback(switch_media_bug_t * bug, void *user_data, switch_abc_type_t type) { - avmd_session_t *avmd_session; - switch_codec_t *read_codec; - switch_frame_t *frame; + avmd_session_t *avmd_session; + switch_codec_t *read_codec; + switch_frame_t *frame; - avmd_session = (avmd_session_t *) user_data; - if (avmd_session == NULL) { - return SWITCH_FALSE; - } + avmd_session = (avmd_session_t *) user_data; + if (avmd_session == NULL) { + return SWITCH_FALSE; + } - switch (type) { + switch (type) { - case SWITCH_ABC_TYPE_INIT: - read_codec = switch_core_session_get_read_codec(avmd_session->session); - avmd_session->rate = read_codec->implementation->samples_per_second; - /* avmd_session->vmd_codec.channels = read_codec->implementation->number_of_channels; */ - break; + case SWITCH_ABC_TYPE_INIT: + read_codec = switch_core_session_get_read_codec(avmd_session->session); + avmd_session->rate = read_codec->implementation->samples_per_second; + /* avmd_session->vmd_codec.channels = read_codec->implementation->number_of_channels; */ + break; - case SWITCH_ABC_TYPE_READ_PING: - case SWITCH_ABC_TYPE_CLOSE: - case SWITCH_ABC_TYPE_READ: - case SWITCH_ABC_TYPE_WRITE: - case SWITCH_ABC_TYPE_TAP_NATIVE_READ: - case SWITCH_ABC_TYPE_TAP_NATIVE_WRITE: - break; + case SWITCH_ABC_TYPE_READ_PING: + case SWITCH_ABC_TYPE_CLOSE: + case SWITCH_ABC_TYPE_READ: + case SWITCH_ABC_TYPE_WRITE: + case SWITCH_ABC_TYPE_TAP_NATIVE_READ: + case SWITCH_ABC_TYPE_TAP_NATIVE_WRITE: + break; - case SWITCH_ABC_TYPE_READ_REPLACE: - frame = switch_core_media_bug_get_read_replace_frame(bug); - avmd_process(avmd_session, frame); - return SWITCH_TRUE; + case SWITCH_ABC_TYPE_READ_REPLACE: + frame = switch_core_media_bug_get_read_replace_frame(bug); + avmd_process(avmd_session, frame); + return SWITCH_TRUE; - case SWITCH_ABC_TYPE_WRITE_REPLACE: - break; - } + case SWITCH_ABC_TYPE_WRITE_REPLACE: + break; + } - return SWITCH_TRUE; + return SWITCH_TRUE; } /*! \brief FreeSWITCH module loading function @@ -214,40 +214,40 @@ static switch_bool_t avmd_callback(switch_media_bug_t * bug, void *user_data, sw SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) { - switch_application_interface_t *app_interface; - switch_api_interface_t *api_interface; - /* connect my internal structure to the blank pointer passed to me */ - *module_interface = switch_loadable_module_create_module_interface(pool, modname); + switch_application_interface_t *app_interface; + switch_api_interface_t *api_interface; + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); - switch_log_printf( - SWITCH_CHANNEL_LOG, - SWITCH_LOG_NOTICE, - "Advanced Voicemail detection enabled\n" - ); + switch_log_printf( + SWITCH_CHANNEL_LOG, + SWITCH_LOG_NOTICE, + "Advanced Voicemail detection enabled\n" + ); #ifdef FASTMATH - init_fast_acosf(); - switch_log_printf( - SWITCH_CHANNEL_LOG, - SWITCH_LOG_NOTICE, - "Advanced Voicemail detection: fast math enabled\n" - ); + init_fast_acosf(); + switch_log_printf( + SWITCH_CHANNEL_LOG, + SWITCH_LOG_NOTICE, + "Advanced Voicemail detection: fast math enabled\n" + ); #endif - SWITCH_ADD_APP( - app_interface, - "avmd", - "Beep detection", - "Advanced detection of voicemail beeps", - avmd_start_function, - "[start] [stop]", - SAF_NONE - ); + SWITCH_ADD_APP( + app_interface, + "avmd", + "Beep detection", + "Advanced detection of voicemail beeps", + avmd_start_function, + "[start] [stop]", + SAF_NONE + ); - SWITCH_ADD_API(api_interface, "avmd", "Voicemail beep detection", avmd_api_main, AVMD_SYNTAX); + SWITCH_ADD_API(api_interface, "avmd", "Voicemail beep detection", avmd_api_main, AVMD_SYNTAX); - /* indicate that the module should continue to be loaded */ - return SWITCH_STATUS_SUCCESS; + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; } /*! \brief FreeSWITCH application handler function. @@ -258,63 +258,63 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) */ SWITCH_STANDARD_APP(avmd_start_function) { - switch_media_bug_t *bug; - switch_status_t status; - switch_channel_t *channel; - avmd_session_t *avmd_session; + switch_media_bug_t *bug; + switch_status_t status; + switch_channel_t *channel; + avmd_session_t *avmd_session; - if (session == NULL) - return; + if (session == NULL) + return; - channel = switch_core_session_get_channel(session); + channel = switch_core_session_get_channel(session); - /* Is this channel already using avmd ? */ - bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_avmd_"); - /* If it is using avmd */ - if (bug != NULL) { - /* If we have a stop remove audio bug */ - if (strcasecmp(data, "stop") == 0) { - switch_channel_set_private(channel, "_avmd_", NULL); - switch_core_media_bug_remove(session, &bug); - return; - } + /* Is this channel already using avmd ? */ + bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_avmd_"); + /* If it is using avmd */ + if (bug != NULL) { + /* If we have a stop remove audio bug */ + if (strcasecmp(data, "stop") == 0) { + switch_channel_set_private(channel, "_avmd_", NULL); + switch_core_media_bug_remove(session, &bug); + return; + } - /* We have already started */ - switch_log_printf( - SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_WARNING, - "Cannot run 2 at once on the same channel!\n" - ); + /* We have already started */ + switch_log_printf( + SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_WARNING, + "Cannot run 2 at once on the same channel!\n" + ); - return; - } + return; + } - avmd_session = (avmd_session_t *)switch_core_session_alloc(session, sizeof(avmd_session_t)); + avmd_session = (avmd_session_t *)switch_core_session_alloc(session, sizeof(avmd_session_t)); - init_avmd_session_data(avmd_session, session); + init_avmd_session_data(avmd_session, session); - status = switch_core_media_bug_add( - session, - "avmd", - NULL, - avmd_callback, - avmd_session, - 0, - SMBF_READ_REPLACE, - &bug - ); + status = switch_core_media_bug_add( + session, + "avmd", + NULL, + avmd_callback, + avmd_session, + 0, + SMBF_READ_REPLACE, + &bug + ); - if (status != SWITCH_STATUS_SUCCESS) { - switch_log_printf( - SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_ERROR, - "Failure hooking to stream\n" - ); + if (status != SWITCH_STATUS_SUCCESS) { + switch_log_printf( + SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_ERROR, + "Failure hooking to stream\n" + ); - return; - } + return; + } - switch_channel_set_private(channel, "_avmd_", bug); + switch_channel_set_private(channel, "_avmd_", bug); } /*! \brief Called when the module shuts down @@ -326,16 +326,16 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) { #ifdef FASTMATH - destroy_fast_acosf(); + destroy_fast_acosf(); #endif - switch_log_printf( - SWITCH_CHANNEL_LOG, - SWITCH_LOG_NOTICE, - "Advanced Voicemail detection disabled\n" - ); + switch_log_printf( + SWITCH_CHANNEL_LOG, + SWITCH_LOG_NOTICE, + "Advanced Voicemail detection disabled\n" + ); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } /*! \brief FreeSWITCH API handler function. @@ -347,127 +347,127 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) */ SWITCH_STANDARD_API(avmd_api_main) { - switch_core_session_t *fs_session = NULL; - switch_media_bug_t *bug; - avmd_session_t *avmd_session; - switch_channel_t *channel; - switch_status_t status; - int argc; - char *argv[AVMD_PARAMS]; - char *ccmd = NULL; - char *uuid; - char *command; + switch_core_session_t *fs_session = NULL; + switch_media_bug_t *bug; + avmd_session_t *avmd_session; + switch_channel_t *channel; + switch_status_t status; + int argc; + char *argv[AVMD_PARAMS]; + char *ccmd = NULL; + char *uuid; + char *command; - /* No command? Display usage */ - if (zstr(cmd)) { - stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); - return SWITCH_STATUS_SUCCESS; - } + /* No command? Display usage */ + if (zstr(cmd)) { + stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); + return SWITCH_STATUS_SUCCESS; + } - /* Duplicated contents of original string */ - ccmd = strdup(cmd); - /* Separate the arguments */ - argc = switch_separate_string(ccmd, ' ', argv, AVMD_PARAMS); + /* Duplicated contents of original string */ + ccmd = strdup(cmd); + /* Separate the arguments */ + argc = switch_separate_string(ccmd, ' ', argv, AVMD_PARAMS); - /* If we don't have the expected number of parameters - * display usage */ - if (argc != AVMD_PARAMS) { - stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); - goto end; - } + /* If we don't have the expected number of parameters + * display usage */ + if (argc != AVMD_PARAMS) { + stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); + goto end; + } - uuid = argv[0]; - command = argv[1]; + uuid = argv[0]; + command = argv[1]; - /* using uuid locate a reference to the FreeSWITCH session */ - fs_session = switch_core_session_locate(uuid); + /* using uuid locate a reference to the FreeSWITCH session */ + fs_session = switch_core_session_locate(uuid); - /* If the session was not found exit */ - if (fs_session == NULL) { - stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); - goto end; - } + /* If the session was not found exit */ + if (fs_session == NULL) { + stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); + goto end; + } - /* Get current channel of the session to tag the session - * This indicates that our module is present */ - channel = switch_core_session_get_channel(fs_session); + /* Get current channel of the session to tag the session + * This indicates that our module is present */ + channel = switch_core_session_get_channel(fs_session); - /* Is this channel already set? */ - bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_avmd_"); - /* If yes */ - if (bug != NULL) { - /* If we have a stop remove audio bug */ - if (strcasecmp(command, "stop") == 0) { - switch_channel_set_private(channel, "_avmd_", NULL); - switch_core_media_bug_remove(fs_session, &bug); - switch_safe_free(ccmd); - stream->write_function(stream, "+OK\n"); - goto end; - } + /* Is this channel already set? */ + bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_avmd_"); + /* If yes */ + if (bug != NULL) { + /* If we have a stop remove audio bug */ + if (strcasecmp(command, "stop") == 0) { + switch_channel_set_private(channel, "_avmd_", NULL); + switch_core_media_bug_remove(fs_session, &bug); + switch_safe_free(ccmd); + stream->write_function(stream, "+OK\n"); + goto end; + } - /* We have already started */ - switch_log_printf( - SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_WARNING, - "Cannot run 2 at once on the same channel!\n" - ); + /* We have already started */ + switch_log_printf( + SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_WARNING, + "Cannot run 2 at once on the same channel!\n" + ); - goto end; - } + goto end; + } - /* If we don't see the expected start exit */ - if (strcasecmp(command, "start") != 0) { - stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); - goto end; - } + /* If we don't see the expected start exit */ + if (strcasecmp(command, "start") != 0) { + stream->write_function(stream, "-USAGE: %s\n", AVMD_SYNTAX); + goto end; + } - /* Allocate memory attached to this FreeSWITCH session for - * use in the callback routine and to store state information */ - avmd_session = (avmd_session_t *) switch_core_session_alloc(fs_session, sizeof(avmd_session_t)); + /* Allocate memory attached to this FreeSWITCH session for + * use in the callback routine and to store state information */ + avmd_session = (avmd_session_t *) switch_core_session_alloc(fs_session, sizeof(avmd_session_t)); - init_avmd_session_data(avmd_session, fs_session); + init_avmd_session_data(avmd_session, fs_session); - /* Add a media bug that allows me to intercept the - * reading leg of the audio stream */ - status = switch_core_media_bug_add( - fs_session, - "avmd", - NULL, - avmd_callback, - avmd_session, - 0, - SMBF_READ_REPLACE, - &bug - ); + /* Add a media bug that allows me to intercept the + * reading leg of the audio stream */ + status = switch_core_media_bug_add( + fs_session, + "avmd", + NULL, + avmd_callback, + avmd_session, + 0, + SMBF_READ_REPLACE, + &bug + ); - /* If adding a media bug fails exit */ - if (status != SWITCH_STATUS_SUCCESS) { + /* If adding a media bug fails exit */ + if (status != SWITCH_STATUS_SUCCESS) { - switch_log_printf( - SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_ERROR, - "Failure hooking to stream\n" - ); + switch_log_printf( + SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_ERROR, + "Failure hooking to stream\n" + ); - goto end; - } + goto end; + } - /* Set the vmd tag to detect an existing vmd media bug */ - switch_channel_set_private(channel, "_avmd_", bug); + /* Set the vmd tag to detect an existing vmd media bug */ + switch_channel_set_private(channel, "_avmd_", bug); - /* Everything went according to plan! Notify the user */ - stream->write_function(stream, "+OK\n"); + /* Everything went according to plan! Notify the user */ + stream->write_function(stream, "+OK\n"); end: - if (fs_session) { - switch_core_session_rwunlock(fs_session); - } + if (fs_session) { + switch_core_session_rwunlock(fs_session); + } - switch_safe_free(ccmd); + switch_safe_free(ccmd); - return SWITCH_STATUS_SUCCESS; + return SWITCH_STATUS_SUCCESS; } /*! \brief Process one frame of data with avmd algorithm @@ -477,102 +477,102 @@ end: */ static void avmd_process(avmd_session_t *session, switch_frame_t *frame) { - switch_event_t *event; - switch_status_t status; - switch_event_t *event_copy; - switch_channel_t *channel; + switch_event_t *event; + switch_status_t status; + switch_event_t *event_copy; + switch_channel_t *channel; - circ_buffer_t *b; - size_t pos; - double f; - double v; -// double error = 0.0; -// double success = 0.0; -// double amp = 0.0; -// double s_rate; -// double e_rate; -// double avg_a; - //double sine_len; - uint32_t sine_len_i; - //uint32_t beep_len_i; -// int valid; + circ_buffer_t *b; + size_t pos; + double f; + double v; + // double error = 0.0; + // double success = 0.0; + // double amp = 0.0; + // double s_rate; + // double e_rate; + // double avg_a; + //double sine_len; + uint32_t sine_len_i; + //uint32_t beep_len_i; + // int valid; b = &session->b; /*! If beep has already been detected skip the CPU heavy stuff */ - if(session->state.beep_state == BEEP_DETECTED){ - return; - } + if(session->state.beep_state == BEEP_DETECTED){ + return; + } /*! Precompute values used heavily in the inner loop */ - sine_len_i = SINE_LEN(session->rate); - //sine_len = (double)sine_len_i; - //beep_len_i = BEEP_LEN(session->rate); - - channel = switch_core_session_get_channel(session->session); + sine_len_i = SINE_LEN(session->rate); + //sine_len = (double)sine_len_i; + //beep_len_i = BEEP_LEN(session->rate); + + channel = switch_core_session_get_channel(session->session); /*! Insert frame of 16 bit samples into buffer */ - INSERT_INT16_FRAME(b, (int16_t *)(frame->data), frame->samples); + INSERT_INT16_FRAME(b, (int16_t *)(frame->data), frame->samples); - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO, "<<< AVMD sine_len_i=%d >>>\n", sine_len_i); + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO, "<<< AVMD sine_len_i=%d >>>\n", sine_len_i); - /*! INNER LOOP -- OPTIMIZATION TARGET */ - for(pos = session->pos; pos < (GET_CURRENT_POS(b) - P); pos++){ - if ((pos % sine_len_i) == 0) { - /*! Get a desa2 frequency estimate every sine len */ - f = desa2(b, pos); + /*! INNER LOOP -- OPTIMIZATION TARGET */ + for(pos = session->pos; pos < (GET_CURRENT_POS(b) - P); pos++){ + if ((pos % sine_len_i) == 0) { + /*! Get a desa2 frequency estimate every sine len */ + f = desa2(b, pos); - if(f < MIN_FREQUENCY_R(session->rate) || f > MAX_FREQUENCY_R(session->rate)) { - v = 99999.0; - RESET_SMA_BUFFER(&session->sma_b); - RESET_SMA_BUFFER(&session->sqa_b); - } else { - APPEND_SMA_VAL(&session->sma_b, f); - APPEND_SMA_VAL(&session->sqa_b, f * f); - - /* calculate variance */ - v = session->sqa_b.sma - (session->sma_b.sma * session->sma_b.sma); + if(f < MIN_FREQUENCY_R(session->rate) || f > MAX_FREQUENCY_R(session->rate)) { + v = 99999.0; + RESET_SMA_BUFFER(&session->sma_b); + RESET_SMA_BUFFER(&session->sqa_b); + } else { + APPEND_SMA_VAL(&session->sma_b, f); + APPEND_SMA_VAL(&session->sqa_b, f * f); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG, "<<< AVMD v=%f f=%f %fHz sma=%f sqa=%f >>>\n", v, f, TO_HZ(session->rate, f), session->sma_b.sma, session->sqa_b.sma); - } + /* calculate variance */ + v = session->sqa_b.sma - (session->sma_b.sma * session->sma_b.sma); - /*! If variance is less than threshold then we have detection */ - if(v < VARIANCE_THRESHOLD){ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG, "<<< AVMD v=%f f=%f %fHz sma=%f sqa=%f >>>\n", v, f, TO_HZ(session->rate, f), session->sma_b.sma, session->sqa_b.sma); + } + + /*! If variance is less than threshold then we have detection */ + if(v < VARIANCE_THRESHOLD){ switch_channel_execute_on(switch_core_session_get_channel(session->session), "execute_on_avmd_beep"); /*! Throw an event to FreeSWITCH */ - status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP); - if(status != SWITCH_STATUS_SUCCESS) { - return; - } + status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP); + if(status != SWITCH_STATUS_SUCCESS) { + return; + } - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session->session)); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "stop"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session->session)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd"); - if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) { - return; - } + if ((switch_event_dup(&event_copy, event)) != SWITCH_STATUS_SUCCESS) { + return; + } - switch_core_session_queue_event(session->session, &event); - switch_event_fire(&event_copy); + switch_core_session_queue_event(session->session, &event); + switch_event_fire(&event_copy); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG, "<<< AVMD - Beep Detected >>>\n"); - switch_channel_set_variable(channel, "avmd_detect", "TRUE"); - RESET_SMA_BUFFER(&session->sma_b); - RESET_SMA_BUFFER(&session->sqa_b); - session->state.beep_state = BEEP_DETECTED; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_DEBUG, "<<< AVMD - Beep Detected >>>\n"); + switch_channel_set_variable(channel, "avmd_detect", "TRUE"); + RESET_SMA_BUFFER(&session->sma_b); + RESET_SMA_BUFFER(&session->sqa_b); + session->state.beep_state = BEEP_DETECTED; - return; - } + return; + } - //amp = 0.0; - //success = 0.0; - //error = 0.0; - } - } - session->pos = pos; + //amp = 0.0; + //success = 0.0; + //error = 0.0; + } + } + session->pos = pos; } /* For Emacs: From 2c5a861b033713a79517637f064ab0d8614733e8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 3 Jan 2014 23:43:42 +0500 Subject: [PATCH 226/656] FS-6074 --resolve --- .../event_handlers/mod_event_socket/mod_event_socket.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index 0c5cd880db..8c0c85911a 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -1569,12 +1569,18 @@ static switch_bool_t auth_api_command(listener_t *listener, const char *api_cmd, static switch_status_t parse_command(listener_t *listener, switch_event_t **event, char *reply, uint32_t reply_len) { switch_status_t status = SWITCH_STATUS_SUCCESS; - char *cmd = switch_event_get_header(*event, "command"); + char *cmd = NULL; char unload_cheat[] = "api bgapi unload mod_event_socket"; char reload_cheat[] = "api bgapi reload mod_event_socket"; *reply = '\0'; + if (!event || !*event || !(cmd = switch_event_get_header(*event, "command"))) { + switch_clear_flag_locked(listener, LFLAG_RUNNING); + switch_snprintf(reply, reply_len, "-ERR command parse error."); + goto done; + } + if (switch_stristr("unload", cmd) && switch_stristr("mod_event_socket", cmd)) { cmd = unload_cheat; } else if (switch_stristr("reload", cmd) && switch_stristr("mod_event_socket", cmd)) { From 3ca06e1ea7fd073dd4b81704d481148b628a7688 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 3 Jan 2014 23:45:35 +0500 Subject: [PATCH 227/656] FS-6073 --resolve --- src/switch_core_media.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d77e430b83..c7fec519ac 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4899,14 +4899,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } } - if ((val = switch_channel_get_variable(session->channel, "params->rtp_timeout_sec"))) { + if ((val = switch_channel_get_variable(session->channel, "rtp_timeout_sec"))) { int v = atoi(val); if (v >= 0) { smh->mparams->rtp_timeout_sec = v; } } - if ((val = switch_channel_get_variable(session->channel, "params->rtp_hold_timeout_sec"))) { + if ((val = switch_channel_get_variable(session->channel, "rtp_hold_timeout_sec"))) { int v = atoi(val); if (v >= 0) { smh->mparams->rtp_hold_timeout_sec = v; From ae7371e7c577599174db937aa555e1ca20167551 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Fri, 3 Jan 2014 16:21:29 -0500 Subject: [PATCH 228/656] mod_http_cache: allow underscore in amazon s3 hostname --- src/mod/applications/mod_http_cache/aws.c | 2 +- src/mod/applications/mod_http_cache/test_aws/main.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_http_cache/aws.c b/src/mod/applications/mod_http_cache/aws.c index 17d6a233ab..cb6db5cb58 100644 --- a/src/mod/applications/mod_http_cache/aws.c +++ b/src/mod/applications/mod_http_cache/aws.c @@ -44,7 +44,7 @@ int aws_s3_is_s3_url(const char *url) { /* AWS bucket naming rules are complex... this match only supports virtual hosting of buckets */ - return !zstr(url) && switch_regex_match(url, "^https?://[a-z0-9][-a-z0-9.]{1,61}[a-z0-9]\\.s3\\.amazonaws\\.com/.*$") == SWITCH_STATUS_SUCCESS; + return !zstr(url) && switch_regex_match(url, "^https?://[a-z0-9_][-a-z0-9._]{1,61}[a-z0-9_]\\.s3\\.amazonaws\\.com/.*$") == SWITCH_STATUS_SUCCESS; } /** diff --git a/src/mod/applications/mod_http_cache/test_aws/main.c b/src/mod/applications/mod_http_cache/test_aws/main.c index 8610127bbe..6c361ca8f1 100644 --- a/src/mod/applications/mod_http_cache/test_aws/main.c +++ b/src/mod/applications/mod_http_cache/test_aws/main.c @@ -48,6 +48,7 @@ static void test_check_url(void) ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/object")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/recordings/1240fwjf8we.mp3")); ASSERT_TRUE(aws_s3_is_s3_url("https://bucket.s3.amazonaws.com/en/us/8000/1232345.mp3")); + ASSERT_TRUE(aws_s3_is_s3_url("https://bucket_with_underscore.s3.amazonaws.com/en/us/8000/1232345.mp3")); ASSERT_FALSE(aws_s3_is_s3_url("bucket.s3.amazonaws.com/object.ext")); ASSERT_FALSE(aws_s3_is_s3_url("https://s3.amazonaws.com/bucket/object")); ASSERT_FALSE(aws_s3_is_s3_url("http://s3.amazonaws.com/bucket/object")); From a14ad62e327634b66cf86ee59c23e295fb55e1d2 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 4 Jan 2014 16:53:36 +0800 Subject: [PATCH 229/656] return +OK on success --- src/mod/applications/mod_commands/mod_commands.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index be2d36cb4f..2b21821ccc 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -3187,8 +3187,13 @@ SWITCH_STANDARD_API(uuid_answer_function) if (uuid && (xsession = switch_core_session_locate(uuid))) { switch_channel_t *channel = switch_core_session_get_channel(xsession); - switch_channel_answer(channel); + switch_status_t status = switch_channel_answer(channel); switch_core_session_rwunlock(xsession); + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK\n"); + } else { + stream->write_function(stream, "-ERROR\n"); + } } else { stream->write_function(stream, "-ERROR\n"); } From e6ec1478efe72aba2afa0ff4169f0f3256c84a94 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 4 Jan 2014 19:57:25 +0000 Subject: [PATCH 230/656] Fix dependency of freeswitch-all-dbg Previously we were trying to rely on freeswitch-all providing freeswitch, but that doesn't seem to work as expected. --- debian/bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index dbe0491ee4..aea8a3fe68 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -744,7 +744,7 @@ Architecture: any Provides: $(list_freeswitch_all_dbg_provides) Replaces: $(list_freeswitch_all_dbg_replaces) Breaks: $(list_freeswitch_all_dbg_replaces) -Depends: \${misc:Depends}, freeswitch (= \${binary:Version}) +Depends: \${misc:Depends}, freeswitch-all (= \${binary:Version}) Description: debugging symbols for FreeSWITCH $(debian_wrap "${fs_description}") . From 91f210a5fc09828a8fcb8197fb9c329a3bc46ced Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Sat, 4 Jan 2014 15:18:10 -0500 Subject: [PATCH 231/656] mod_rayo CPA - added detector abstraction --- conf/rayo/autoload_configs/rayo.conf.xml | 53 +++ src/mod/event_handlers/mod_rayo/Makefile | 2 + .../conf/autoload_configs/rayo.conf.xml | 53 +++ .../mod_rayo/rayo_cpa_detector.c | 435 ++++++++++++++++++ .../mod_rayo/rayo_cpa_detector.h | 68 +++ .../mod_rayo/rayo_input_component.c | 6 +- 6 files changed, 616 insertions(+), 1 deletion(-) create mode 100644 src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c create mode 100644 src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index 9a8900dbfa..45a8ab04bb 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -22,6 +22,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/event_handlers/mod_rayo/Makefile b/src/mod/event_handlers/mod_rayo/Makefile index a3bfc45d47..3b7e5dba3f 100644 --- a/src/mod/event_handlers/mod_rayo/Makefile +++ b/src/mod/event_handlers/mod_rayo/Makefile @@ -10,6 +10,7 @@ LOCAL_OBJS= $(IKS_LA) \ iks_helpers.o \ nlsml.o \ rayo_components.o \ + rayo_cpa_detector.o \ rayo_elements.o \ rayo_fax_components.o \ rayo_input_component.o \ @@ -23,6 +24,7 @@ LOCAL_SOURCES= \ iks_helpers.c \ nlsml.c \ rayo_components.c \ + rayo_cpa_detector.c \ rayo_elements.c \ rayo_fax_components.c \ rayo_input_component.c \ diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index 9a8900dbfa..45a8ab04bb 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -22,6 +22,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c new file mode 100644 index 0000000000..9267e05456 --- /dev/null +++ b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c @@ -0,0 +1,435 @@ +/* + * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2014, Grasshopper + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is Grasshopper + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Rienzo + * + * rayo_cpa_detector.c -- Glue to normalize events from and to allow multiple instantiation of various detectors in FreeSWITCH + */ + +#include "rayo_cpa_detector.h" + +static struct { + /** detectors supported by this module mapped by signal-type */ + switch_hash_t *detectors; +} globals; + +struct rayo_cpa_detector; + +/** + * Detector definition + */ +struct rayo_cpa_detector { + /** unique internal name of this detector */ + const char *name; + /** detector ID */ + const char *uuid; + /** start detection APP */ + const char *start_app; + /** args to pass to start detection app */ + const char *start_app_args; + /** stop detection APP */ + const char *stop_app; + /** args to pass to stop detection app */ + const char *stop_app_args; + /** (optional) name of header to get the signal type from */ + const char *signal_type_header; + /** (optional) where to get the signal value from the event */ + const char *signal_value_header; + /** (optional) where to get the signal duration from the event */ + const char *signal_duration_header; + /** detector event to signal type mapping */ + switch_hash_t *signal_type_map; +}; + +/** + * Detection state + */ +struct rayo_cpa_detector_state { + /** reference count */ + int refs; +}; + +/** + * Start detecting + * @param call_uuid call to detect signal on + * @param signal_ns namespace of signal to detect + * @param error_detail on failure, describes the error + * @return 1 if successful, 0 if failed + */ +int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail) +{ + struct rayo_cpa_detector *detector = switch_core_hash_find(globals.detectors, signal_ns); + if (detector) { + switch_core_session_t *session = switch_core_session_locate(call_uuid); + if (session) { + struct rayo_cpa_detector_state *detector_state = switch_channel_get_private(switch_core_session_get_channel(session), detector->uuid); + if (detector_state) { + /* detector is already running */ + detector_state->refs++; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Start detector %s, refs = %d\n", detector->name, detector_state->refs); + switch_core_session_rwunlock(session); + return 1; + } + detector_state = switch_core_session_alloc(session, sizeof(*detector_state)); + detector_state->refs = 1; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Starting detector %s, refs = 1\n", detector->name); + switch_channel_set_private(switch_core_session_get_channel(session), detector->uuid, detector_state); + switch_core_session_execute_application_async(session, detector->start_app, zstr(detector->start_app_args) ? NULL : detector->start_app_args); + switch_core_session_rwunlock(session); + return 1; + } else { + *error_detail = "session gone"; + return 0; + } + } + *error_detail = "detector not supported"; + return 0; +} + +/** + * Stop detecting + * @param call_uuid call to stop detecting signal on + * @param signal_ns name of signal to stop detecting + */ +void rayo_cpa_detector_stop(const char *call_uuid, const char *signal_ns) +{ + struct rayo_cpa_detector *detector = switch_core_hash_find(globals.detectors, signal_ns); + if (detector) { + switch_core_session_t *session = switch_core_session_locate(call_uuid); + if (session) { + struct rayo_cpa_detector_state *detector_state = switch_channel_get_private(switch_core_session_get_channel(session), detector->uuid); + if (detector_state) { + detector_state->refs--; + if (detector_state->refs < 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Stop detector %s refs = %d\n", detector->name, detector_state->refs); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stop detector %s refs = %d\n", detector->name, detector_state->refs); + } + if (detector_state->refs == 0) { + /* nobody interested in detector events- shut it down */ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stopping detector %s\n", detector->name); + switch_core_session_execute_application_async(session, detector->stop_app, zstr(detector->stop_app_args) ? NULL : detector->stop_app_args); + switch_channel_set_private(switch_core_session_get_channel(session), detector->uuid, NULL); + } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Detector %s is already stopped\n", detector->name); + } + switch_core_session_rwunlock(session); + } + } +} + +/** + * Handle event from detector + */ +static void rayo_cpa_detector_event(switch_event_t *event) +{ + struct rayo_cpa_detector *detector = (struct rayo_cpa_detector *)event->bind_user_data; + if (detector) { + const char *signal_type = "rayo_default"; + if (!zstr(detector->signal_type_header)) { + signal_type = switch_event_get_header(event, detector->signal_type_header); + } + if (!zstr(signal_type)) { + signal_type = switch_core_hash_find(detector->signal_type_map, signal_type); + } + if (!zstr(signal_type)) { + switch_event_t *cpa_event; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got Rayo CPA event %s\n", signal_type); + if (switch_event_create_subclass(&cpa_event, SWITCH_EVENT_CUSTOM, "rayo::cpa") == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "detector-name", detector->name); + switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "detector-uuid", detector->uuid); + switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "signal-type", signal_type); + if (!zstr(detector->signal_value_header)) { + const char *value = switch_event_get_header(event, detector->signal_value_header); + if (!zstr(value)) { + switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "value", value); + } + } + if (!zstr(detector->signal_duration_header)) { + const char *duration = switch_event_get_header(event, detector->signal_duration_header); + if (!zstr(duration)) { + switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "duration", duration); + } + } + switch_event_fire(&cpa_event); + } + } else { + /* couldn't map event to Rayo signal-type */ + const char *event_name = switch_event_get_header(event, "Event-Name"); + const char *event_subclass = switch_event_get_header(event, "Event-Subclass"); + if (zstr(event_subclass)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to find Rayo signal-type for event %s\n", event_name); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Failed to find Rayo signal-type for event %s %s\n", event_name, event_subclass); + } + } + } +} + +#define RAYO_CPA_DETECTOR_SYNTAX "rayo_cpa " +SWITCH_STANDARD_API(rayo_cpa_detector_api) +{ + char *cmd_dup = NULL; + char *argv[4] = { 0 }; + int argc = 0; + + if (zstr(cmd)) { + stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_CPA_DETECTOR_SYNTAX); + goto done; + } + + cmd_dup = strdup(cmd); + argc = switch_separate_string(cmd_dup, ' ', argv, sizeof(argv) / sizeof(argv[0])); + + if (argc != 3) { + stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_CPA_DETECTOR_SYNTAX); + } else { + const char *err_reason = NULL; + if (!strcmp(argv[2], "stop")) { + rayo_cpa_detector_stop(argv[0], argv[1]); + stream->write_function(stream, "+OK\n"); + } else if (!strcmp(argv[2], "start")) { + if (!rayo_cpa_detector_start(argv[0], argv[1], &err_reason)) { + if (err_reason) { + stream->write_function(stream, "-ERR: %s\n", err_reason); + } else { + stream->write_function(stream, "-ERR\n"); + } + } else { + stream->write_function(stream, "+OK\n"); + } + } else { + stream->write_function(stream, "-ERR: USAGE %s\n", RAYO_CPA_DETECTOR_SYNTAX); + } + } + +done: + switch_safe_free(cmd_dup); + + return SWITCH_STATUS_SUCCESS; +} + +/** + * Configure CPA + */ +static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_file) +{ + switch_xml_t cfg, xml, cpa_xml; + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_hash_t *bound_events; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Configuring CPA\n"); + if (!(xml = switch_xml_open_cfg(config_file, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", config_file); + return SWITCH_STATUS_TERM; + } + + switch_core_hash_init(&bound_events, pool); + + cpa_xml = switch_xml_child(cfg, "cpa"); + if (cpa_xml) { + switch_xml_t detector_xml; + + for (detector_xml = switch_xml_child(cpa_xml, "detector"); detector_xml; detector_xml = detector_xml->next) { + switch_xml_t start_xml, stop_xml, event_xml; + struct rayo_cpa_detector *detector; + char id[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 }; + const char *name = switch_xml_attr_soft(detector_xml, "name"); + if (zstr(name)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing name of CPA detector!\n"); + status = SWITCH_STATUS_TERM; + goto done; + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CPA detector: %s\n", name); + detector = switch_core_alloc(pool, sizeof(*detector)); + switch_core_hash_init(&detector->signal_type_map, pool); + detector->name = switch_core_strdup(pool, name); + switch_uuid_str(id, sizeof(id)); + detector->uuid = switch_core_strdup(pool, id); + + start_xml = switch_xml_child(detector_xml, "start"); + if (start_xml) { + detector->start_app = switch_core_strdup(pool, switch_xml_attr_soft(start_xml, "application")); + detector->start_app_args = switch_core_strdup(pool, switch_xml_attr_soft(start_xml, "data")); + } + + stop_xml = switch_xml_child(detector_xml, "stop"); + if (stop_xml) { + detector->stop_app = switch_core_strdup(pool, switch_xml_attr_soft(stop_xml, "application")); + detector->stop_app_args = switch_core_strdup(pool, switch_xml_attr_soft(stop_xml, "data")); + } + + event_xml = switch_xml_child(detector_xml, "event"); + if (event_xml) { + int event_ok = 0; + switch_xml_t signal_type_xml; + const char *event_class = switch_xml_attr_soft(event_xml, "class"); + const char *event_subclass = switch_xml_attr_soft(event_xml, "subclass"); + switch_event_types_t event_type; + if (zstr(event_class)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing event class for CPA detector: %s\n", detector->name); + status = SWITCH_STATUS_TERM; + goto done; + } + + if (switch_name_event(event_class, &event_type) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event class %s for CPA detector: %s\n", event_class, detector->name); + status = SWITCH_STATUS_TERM; + goto done; + } + + /* bind detector to event if not already done... */ + { + struct rayo_cpa_detector *bound_detector; + const char *event_name = switch_core_sprintf(pool, "%s %s", event_class, event_subclass); + if (!(bound_detector = switch_core_hash_find(bound_events, event_name))) { + /* not yet bound */ + if (zstr(event_subclass)) { + event_subclass = NULL; + } + switch_event_bind("rayo_cpa_detector", event_type, event_subclass, rayo_cpa_detector_event, detector); + switch_core_hash_insert(bound_events, event_name, detector); /* mark as bound */ + } else if (bound_detector != detector) { + /* can't have multiple detectors generating the same event! */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s attempted to bind to event %s that is already bound by %s\n", detector->name, event_name, bound_detector->name); + status = SWITCH_STATUS_TERM; + goto done; + } + } + + /* configure native event -> rayo CPA event mapping */ + detector->signal_type_header = switch_core_strdup(pool, switch_xml_attr_soft(event_xml, "type-header")); + detector->signal_value_header = switch_core_strdup(pool, switch_xml_attr_soft(event_xml, "value-header")); + detector->signal_duration_header = switch_core_strdup(pool, switch_xml_attr_soft(event_xml, "duration-header")); + + /* configure native event type -> rayo CPA signal type mapping */ + for (signal_type_xml = switch_xml_child(event_xml, "signal-type"); signal_type_xml; signal_type_xml = signal_type_xml->next) { + const char *header_value = switch_core_strdup(pool, switch_xml_attr_soft(signal_type_xml, "header-value")); + const char *signal_type = switch_core_strdup(pool, switch_xml_attr_soft(signal_type_xml, "value")); + if (zstr(signal_type)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s missing signal-type value!\n", detector->name); + status = SWITCH_STATUS_TERM; + goto done; + } else { + /* add signal-type to detector mapping */ + const char *signal_type_ns = switch_core_sprintf(pool, "%s%s:%s", RAYO_CPA_BASE, signal_type, RAYO_VERSION); + event_ok = 1; + switch_core_hash_insert(globals.detectors, signal_type_ns, detector); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding CPA %s => %s\n", signal_type_ns, detector->name); + } + + /* map event value to signal-type */ + if (zstr(header_value)) { + switch_core_hash_insert(detector->signal_type_map, "rayo_default", signal_type); + } else { + switch_core_hash_insert(detector->signal_type_map, header_value, signal_type); + } + } + + if (!event_ok) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s is missing Rayo signal-type for event\n", detector->name); + status = SWITCH_STATUS_TERM; + goto done; + } + } + } + } + +done: + switch_core_hash_destroy(&bound_events); + switch_xml_free(xml); + + return status; +} + +/** + * Console auto-completion for signal types + */ +static switch_status_t rayo_cpa_detector_signal_types(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + switch_hash_index_t *hi; + void *val; + const void *vvar; + switch_console_callback_match_t *my_matches = NULL; + + for (hi = switch_hash_first(NULL, globals.detectors); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &vvar, NULL, &val); + switch_console_push_match(&my_matches, (const char *) vvar); + } + + if (my_matches) { + *matches = my_matches; + status = SWITCH_STATUS_SUCCESS; + } + + return status; +} + +/** + * Load CPA signal detection features + * @param module_interface + * @param pool memory pool + * @param config_file + * @return SWITCH_STATUS_SUCCESS if successfully loaded + */ +switch_status_t rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) +{ + switch_api_interface_t *api_interface; + + SWITCH_ADD_API(api_interface, "rayo_cpa", "Query rayo status", rayo_cpa_detector_api, RAYO_CPA_DETECTOR_SYNTAX); + + switch_console_set_complete("add rayo_cpa ::console::list_uuid ::rayo_cpa::list_signal_types start"); + switch_console_set_complete("add rayo_cpa ::console::list_uuid ::rayo_cpa::list_signal_types stop"); + switch_console_add_complete_func("::rayo_cpa::list_signal_types", rayo_cpa_detector_signal_types); + + switch_core_hash_init(&globals.detectors, pool); + if (do_config(pool, config_file) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_TERM; + } + return SWITCH_STATUS_SUCCESS; +} + +/** + * Disable CPA signal detection features + */ +void rayo_cpa_detector_shutdown(void) +{ + switch_console_set_complete("del rayo_cpa"); + switch_console_del_complete_func("::rayo_cpa::list_signal_types"); + switch_core_hash_destroy(&globals.detectors); + switch_event_unbind_callback(rayo_cpa_detector_event); +} + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet + */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h new file mode 100644 index 0000000000..335d1c3a1b --- /dev/null +++ b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h @@ -0,0 +1,68 @@ +/* + * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2014, Grasshopper + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is Grasshopper + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Rienzo + * + * rayo_cpa_detector.h -- Rayo call progress analysis + * + */ +#ifndef RAYO_CPA_DETECTOR_H +#define RAYO_CPA_DETECTOR_H + +#include + +#include "mod_rayo.h" + +#define RAYO_CPA_BASE RAYO_BASE "cpa:" +#define RAYO_CPA_NS RAYO_CPA_BASE RAYO_VERSION + +#define RAYO_CPA_BEEP_NS RAYO_CPA_BASE "beep:" RAYO_VERSION +#define RAYO_CPA_DTMF_NS RAYO_CPA_BASE "dtmf:" RAYO_VERSION +#define RAYO_CPA_SPEECH_NS RAYO_CPA_BASE "speech:" RAYO_VERSION +#define RAYO_CPA_FAX_CED_NS RAYO_CPA_BASE "fax-ced:" RAYO_VERSION +#define RAYO_CPA_FAX_CNG_NS RAYO_CPA_BASE "fax-cng:" RAYO_VERSION +#define RAYO_CPA_RING_NS RAYO_CPA_BASE "ring:" RAYO_VERSION +#define RAYO_CPA_BUSY_NS RAYO_CPA_BASE "busy:" RAYO_VERSION +#define RAYO_CPA_CONGESTION_NS RAYO_CPA_BASE "congestion:" RAYO_VERSION +#define RAYO_CPA_SIT_NS RAYO_CPA_BASE "sit:" RAYO_VERSION +#define RAYO_CPA_MODEM_NS RAYO_CPA_BASE "modem:" RAYO_VERSION +#define RAYO_CPA_OFFHOOK_NS RAYO_CPA_BASE "offhook:" RAYO_VERSION + +extern switch_status_t rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern void rayo_cpa_detector_shutdown(void); +extern int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail); +extern void rayo_cpa_detector_stop(const char *call_uuid, const char *signal_ns); + +#endif + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet + */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c index 8238deb48a..4ea0e5f600 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_input_component.c @@ -27,6 +27,7 @@ * */ #include "rayo_components.h" +#include "rayo_cpa_detector.h" #include "rayo_elements.h" #include "srgs.h" #include "nlsml.h" @@ -760,7 +761,7 @@ switch_status_t rayo_input_component_load(switch_loadable_module_interface_t **m rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "input", "set:"RAYO_INPUT_NS":start-timers", start_timers_call_input_component); switch_event_bind("rayo_input_component", SWITCH_EVENT_DETECTED_SPEECH, SWITCH_EVENT_SUBCLASS_ANY, on_detected_speech_event, NULL); - return SWITCH_STATUS_SUCCESS; + return rayo_cpa_detector_load(module_interface, pool, config_file); } /** @@ -771,6 +772,9 @@ switch_status_t rayo_input_component_shutdown(void) { srgs_parser_destroy(globals.parser); switch_event_unbind_callback(on_detected_speech_event); + + rayo_cpa_detector_shutdown(); + return SWITCH_STATUS_SUCCESS; } From 85423194f72130b1e4312622ebb98114be5f97fa Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Sat, 4 Jan 2014 21:36:29 -0600 Subject: [PATCH 232/656] FS-5894 --resolve --- .../mod_nibblebill/conf/autoload_configs/nibblebill.conf.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_nibblebill/conf/autoload_configs/nibblebill.conf.xml b/src/mod/applications/mod_nibblebill/conf/autoload_configs/nibblebill.conf.xml index 043c985482..e359049ab5 100644 --- a/src/mod/applications/mod_nibblebill/conf/autoload_configs/nibblebill.conf.xml +++ b/src/mod/applications/mod_nibblebill/conf/autoload_configs/nibblebill.conf.xml @@ -2,8 +2,8 @@ - - + + From 8db351858ba38dba56d1456f0c7fba43e9d8775b Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Sun, 5 Jan 2014 00:39:40 -0500 Subject: [PATCH 233/656] mod_rayo CPA implemented - still needs testing --- conf/rayo/autoload_configs/rayo.conf.xml | 3 + src/mod/event_handlers/mod_rayo/Makefile | 2 + .../conf/autoload_configs/rayo.conf.xml | 3 + src/mod/event_handlers/mod_rayo/mod_rayo.c | 12 +- src/mod/event_handlers/mod_rayo/mod_rayo.h | 10 +- .../mod_rayo/rayo_cpa_component.c | 401 ++++++++++++++++++ .../mod_rayo/rayo_cpa_component.h | 53 +++ .../mod_rayo/rayo_cpa_detector.c | 18 +- .../mod_rayo/rayo_cpa_detector.h | 15 - .../event_handlers/mod_rayo/rayo_elements.c | 2 +- .../mod_rayo/rayo_input_component.c | 21 +- 11 files changed, 508 insertions(+), 32 deletions(-) create mode 100644 src/mod/event_handlers/mod_rayo/rayo_cpa_component.c create mode 100644 src/mod/event_handlers/mod_rayo/rayo_cpa_component.h diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index 45a8ab04bb..52a1a35977 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -109,6 +109,9 @@ + ]]> + ]]> + ]]> ]]> ]]> ]]> diff --git a/src/mod/event_handlers/mod_rayo/Makefile b/src/mod/event_handlers/mod_rayo/Makefile index 3b7e5dba3f..070f41f98c 100644 --- a/src/mod/event_handlers/mod_rayo/Makefile +++ b/src/mod/event_handlers/mod_rayo/Makefile @@ -10,6 +10,7 @@ LOCAL_OBJS= $(IKS_LA) \ iks_helpers.o \ nlsml.o \ rayo_components.o \ + rayo_cpa_component.o \ rayo_cpa_detector.o \ rayo_elements.o \ rayo_fax_components.o \ @@ -24,6 +25,7 @@ LOCAL_SOURCES= \ iks_helpers.c \ nlsml.c \ rayo_components.c \ + rayo_cpa_component.c \ rayo_cpa_detector.c \ rayo_elements.c \ rayo_fax_components.c \ diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index 45a8ab04bb..52a1a35977 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -109,6 +109,9 @@ + ]]> + ]]> + ]]> ]]> ]]> ]]> diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index c650e66877..95162093c8 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -1191,6 +1191,10 @@ static struct rayo_mixer *_rayo_mixer_create(const char *name, const char *file, */ static void rayo_component_cleanup(struct rayo_actor *actor) { + if (RAYO_COMPONENT(actor)->cleanup_fn) { + RAYO_COMPONENT(actor)->cleanup_fn(actor); + } + /* parent can now be destroyed */ RAYO_UNLOCK(RAYO_COMPONENT(actor)->parent); } @@ -1202,9 +1206,12 @@ static void rayo_component_cleanup(struct rayo_actor *actor) * @param id internal ID of this component * @param parent the parent that owns this component * @param client_jid the client that created this component + * @param cleanup optional cleanup function + * @param file file that called this function + * @param line line number that called this function * @return the component */ -struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, const char *file, int line) +struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line) { char *ref = switch_mprintf("%s-%d", subtype, rayo_actor_seq_next(parent)); char *jid = switch_mprintf("%s/%s", RAYO_JID(parent), ref); @@ -1218,6 +1225,7 @@ struct rayo_component *_rayo_component_init(struct rayo_component *component, sw component->client_jid = switch_core_strdup(pool, client_jid); component->ref = switch_core_strdup(pool, ref); component->parent = parent; + component->cleanup_fn = cleanup; switch_safe_free(ref); switch_safe_free(jid); @@ -2443,6 +2451,8 @@ static iks *on_iq_get_xmpp_disco(struct rayo_actor *server, struct rayo_message feature = iks_insert(x, "feature"); iks_insert_attrib(feature, "var", RAYO_NS); feature = iks_insert(x, "feature"); + iks_insert_attrib(feature, "var", RAYO_CPA_NS); + feature = iks_insert(x, "feature"); iks_insert_attrib(feature, "var", RAYO_FAX_NS); /* TODO The response MUST also include features for the application formats and transport methods supported by diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.h b/src/mod/event_handlers/mod_rayo/mod_rayo.h index b862802f31..9d0bf05490 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.h +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.h @@ -42,6 +42,9 @@ #define RAYO_CALL_NS RAYO_BASE "call:" RAYO_VERSION #define RAYO_MIXER_NS RAYO_BASE "mixer:" RAYO_VERSION +#define RAYO_CPA_BASE RAYO_BASE "cpa:" +#define RAYO_CPA_NS RAYO_CPA_BASE RAYO_VERSION + #define RAT_CALL "CALL" #define RAT_COMPONENT "COMPONENT" #define RAT_CALL_COMPONENT RAT_COMPONENT"_CALL" @@ -119,6 +122,8 @@ struct rayo_component { const char *client_jid; /** external ref */ const char *ref; + /** optional cleanup */ + rayo_actor_cleanup_fn cleanup_fn; }; #define RAYO_ACTOR(x) ((struct rayo_actor *)x) @@ -160,8 +165,9 @@ extern const char *rayo_call_get_dcp_jid(struct rayo_call *call); #define rayo_mixer_get_name(mixer) RAYO_ID(mixer) -#define rayo_component_init(component, pool, type, subtype, id, parent, client_jid) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, __FILE__, __LINE__) -extern struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, const char *file, int line); +#define rayo_component_init(component, pool, type, subtype, id, parent, client_jid) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, NULL, __FILE__, __LINE__) +#define rayo_component_init_cleanup(component, pool, type, subtype, id, parent, client_jid, cleanup) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, cleanup, __FILE__, __LINE__) +extern struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line); extern switch_bool_t is_component_actor(struct rayo_actor *); typedef iks *(*rayo_actor_xmpp_handler)(struct rayo_actor *, struct rayo_message *, void *); diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_component.c b/src/mod/event_handlers/mod_rayo/rayo_cpa_component.c new file mode 100644 index 0000000000..8004347118 --- /dev/null +++ b/src/mod/event_handlers/mod_rayo/rayo_cpa_component.c @@ -0,0 +1,401 @@ +/* + * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2014, Grasshopper + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is Grasshopper + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Rienzo + * + * rayo_cpa_component.c -- input component "cpa" mode implementation + */ +#include + +#include "rayo_cpa_component.h" +#include "mod_rayo.h" +#include "rayo_components.h" +#include "rayo_cpa_detector.h" + +/** + * Module globals + */ +struct { + /** signal subscribers */ + switch_hash_t *subscribers; + /** synchronizes access to subscribers */ + switch_mutex_t *subscribers_mutex; + /** module pool */ + switch_memory_pool_t *pool; +} globals; + +/** + * A CPA signal monitored by this component + */ +struct cpa_signal { + /** name of this signal */ + const char *name; + /** true if signal causes component termination */ + int terminate; +}; + +/** + * CPA component state + */ +struct cpa_component { + /** component base class */ + struct rayo_component base; + /** true if ready to forward detector events */ + int ready; + /** signals this component wants */ + switch_hash_t *signals; +}; + +#define CPA_COMPONENT(x) ((struct cpa_component *)x) + +typedef void (* subscriber_execute_fn)(const char *jid, void *user_data); + +/** + * Request signals + */ +static void subscribe(const char *uuid, const char *signal_type, const char *jid) +{ + char *key = switch_mprintf("%s:%s", uuid, signal_type); + switch_mutex_lock(globals.subscribers_mutex); + { + switch_hash_t *signal_subscribers = switch_core_hash_find(globals.subscribers, key); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Subscribe %s => %s\n", signal_type, jid); + if (!signal_subscribers) { + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Create %s subscriber hash\n", signal_type); + switch_core_hash_init(&signal_subscribers, NULL); + switch_core_hash_insert(globals.subscribers, key, signal_subscribers); + } + switch_core_hash_insert(signal_subscribers, jid, "1"); + } + switch_mutex_unlock(globals.subscribers_mutex); + switch_safe_free(key); +} + +/** + * Stop receiving signals + */ +static void unsubscribe(const char *uuid, const char *signal_type, const char *jid) +{ + char *key = switch_mprintf("%s:%s", uuid, signal_type); + switch_mutex_lock(globals.subscribers_mutex); + { + switch_hash_t *signal_subscribers = switch_core_hash_find(globals.subscribers, key); + if (signal_subscribers) { + switch_core_hash_delete(signal_subscribers, jid); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Unsubscribe %s => %s\n", signal_type, jid); + + /* clean up hash if empty */ + if (!switch_core_hash_first(signal_subscribers)) { + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Destroy %s subscriber hash\n", signal_type); + switch_core_hash_destroy(&signal_subscribers); + switch_core_hash_delete(globals.subscribers, key); + } + } + } + switch_mutex_unlock(globals.subscribers_mutex); + switch_safe_free(key); +} + +/** + * Execute function for each subscriber + */ +static void subscriber_execute(const char *uuid, const char *signal_type, subscriber_execute_fn callback, void *user_data) +{ + switch_event_t *subscriber_list = NULL; + switch_event_header_t *subscriber = NULL; + + /* fetch list of subscribers */ + char *key = switch_mprintf("%s:%s", uuid, signal_type); + switch_event_create_subclass(&subscriber_list, SWITCH_EVENT_CLONE, NULL); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Subscriber execute %s\n", signal_type); + switch_mutex_lock(globals.subscribers_mutex); + { + switch_hash_index_t *hi = NULL; + switch_hash_t *signal_subscribers = switch_core_hash_find(globals.subscribers, key); + if (signal_subscribers) { + for (hi = switch_core_hash_first(signal_subscribers); hi; hi = switch_core_hash_next(hi)) { + const void *jid; + void *dont_care; + switch_core_hash_this(hi, &jid, NULL, &dont_care); + switch_event_add_header_string(subscriber_list, SWITCH_STACK_BOTTOM, "execute", (const char *)jid); + } + } else { + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "No subscribers for %s\n", signal_type); + } + } + switch_mutex_unlock(globals.subscribers_mutex); + switch_safe_free(key); + + /* execute function for each subscriber */ + for (subscriber = subscriber_list->headers; subscriber; subscriber = subscriber->next) { + callback(subscriber->value, user_data); + } + + switch_event_destroy(&subscriber_list); +} + +/** + * Stop all CPA detectors + */ +static void stop_cpa_detectors(struct cpa_component *cpa) +{ + if (cpa->signals) { + switch_hash_index_t *hi = NULL; + for (hi = switch_core_hash_first(cpa->signals); hi; hi = switch_core_hash_next(hi)) { + const char *signal_type; + struct cpa_signal *cpa_signal = NULL; + switch_core_hash_this(hi, (const void **)&signal_type, NULL, (void **)&cpa_signal); + if (cpa_signal) { + rayo_cpa_detector_stop(RAYO_COMPONENT(cpa)->parent->id, cpa_signal->name); + unsubscribe(RAYO_COMPONENT(cpa)->parent->id, cpa_signal->name, RAYO_JID(cpa)); + } + } + switch_core_hash_destroy(&cpa->signals); + cpa->signals = NULL; + } + unsubscribe(RAYO_COMPONENT(cpa)->parent->id, "hangup", RAYO_JID(cpa)); +} + +/** + * Stop execution of CPA component + */ +static iks *stop_cpa_component(struct rayo_actor *component, struct rayo_message *msg, void *data) +{ + stop_cpa_detectors(CPA_COMPONENT(component)); + rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_STOP); + return iks_new_iq_result(msg->payload); +} + +/** + * Forward CPA signal to client + */ +static void rayo_cpa_detector_event(const char *jid, void *user_data) +{ + struct rayo_actor *component = RAYO_LOCATE(jid); + if (component) { + if (CPA_COMPONENT(component)->ready) { + switch_event_t *event = (switch_event_t *)user_data; + const char *signal_type = switch_event_get_header(event, "signal-type"); + struct cpa_signal *cpa_signal = switch_core_hash_find(CPA_COMPONENT(component)->signals, signal_type); + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_COMPONENT(component)->parent->id), SWITCH_LOG_DEBUG, "Handling CPA event\n"); + if (cpa_signal) { + const char *value = switch_event_get_header(event, "value"); + const char *duration = switch_event_get_header(event, "duration"); + if (cpa_signal->terminate) { + iks *complete_event; + iks *signal_xml; + + stop_cpa_detectors(CPA_COMPONENT(component)); + + /* send complete event to client */ + complete_event = rayo_component_create_complete_event(RAYO_COMPONENT(component), "signal", RAYO_CPA_NS); + signal_xml = iks_find(complete_event, "complete"); + signal_xml = iks_find(signal_xml, "signal"); + iks_insert_attrib(signal_xml, "type", signal_type); + if (!zstr(value)) { + iks_insert_attrib(signal_xml, "value", value); + } + if (!zstr(duration)) { + iks_insert_attrib(signal_xml, "duration", duration); + } + rayo_component_send_complete_event(RAYO_COMPONENT(component), complete_event); + } else { + /* send event to client */ + iks *signal_event = iks_new_presence("signal", RAYO_CPA_NS, RAYO_JID(component), RAYO_COMPONENT(component)->client_jid); + iks *signal_xml = iks_find(signal_event, "signal"); + iks_insert_attrib(signal_xml, "type", signal_type); + if (!zstr(value)) { + iks_insert_attrib(signal_xml, "value", value); + } + if (!zstr(duration)) { + iks_insert_attrib(signal_xml, "duration", duration); + } + RAYO_SEND_REPLY(component, RAYO_COMPONENT(component)->client_jid, signal_event); + } + } + } else { + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(RAYO_COMPONENT(component)->parent->id), SWITCH_LOG_DEBUG, "Skipping CPA event\n"); + } + RAYO_UNLOCK(component); + } +} + +/** + * Handle CPA signal-type event + */ +static void on_rayo_cpa_detector_event(switch_event_t *event) +{ + subscriber_execute(switch_event_get_header(event, "Unique-ID"), switch_event_get_header(event, "signal-type"), rayo_cpa_detector_event, event); +} + +/** + * Handle CPA completion because of hangup + */ +static void rayo_cpa_component_hangup(const char *jid, void *user_data) +{ + struct rayo_actor *component = RAYO_LOCATE(jid); + if (component) { + stop_cpa_detectors(CPA_COMPONENT(component)); + rayo_component_send_complete(RAYO_COMPONENT(component), COMPONENT_COMPLETE_HANGUP); + RAYO_UNLOCK(component); + } +} + +/** + * Handle hungup call event + */ +static void on_channel_hangup_complete_event(switch_event_t *event) +{ + subscriber_execute(switch_event_get_header(event, "Unique-ID"), "hangup", rayo_cpa_component_hangup, event); +} + +/** + * Start CPA + */ +iks *rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data) +{ + iks *iq = msg->payload; + switch_core_session_t *session = (switch_core_session_t *)session_data; + iks *input = iks_find(iq, "input"); + switch_memory_pool_t *pool = NULL; + struct cpa_component *component = NULL; + int have_grammar = 0; + iks *grammar = NULL; + + /* create CPA component */ + switch_core_new_memory_pool(&pool); + component = switch_core_alloc(pool, sizeof(*component)); + rayo_component_init((struct rayo_component *)component, pool, RAT_CALL_COMPONENT, "cpa", NULL, call, iks_find_attrib(iq, "from")); + + switch_core_hash_init(&component->signals, pool); + + /* start CPA detectors */ + for (grammar = iks_find(input, "grammar"); grammar; grammar = iks_next_tag(grammar)) { + if (!strcmp("grammar", iks_name(grammar))) { + const char *error_str = ""; + const char *url = iks_find_attrib_soft(grammar, "url"); + char *url_dup; + char *url_params; + + if (zstr(url)) { + stop_cpa_detectors(component); + RAYO_UNLOCK(component); + RAYO_DESTROY(component); + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Missing grammar URL"); + } + have_grammar = 1; + + url_dup = strdup(url); + if ((url_params = strchr(url_dup, '?'))) { + *url_params = '\0'; + url_params++; + } + + if (switch_core_hash_find(component->signals, url)) { + free(url_dup); + stop_cpa_detectors(component); + RAYO_UNLOCK(component); + RAYO_DESTROY(component); + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "Duplicate URL"); + } + + /* start detector */ + /* TODO return better reasons... */ + if (rayo_cpa_detector_start(switch_core_session_get_uuid(session), url_dup, &error_str)) { + struct cpa_signal *cpa_signal = switch_core_alloc(pool, sizeof(*cpa_signal)); + cpa_signal->terminate = !zstr(url_params) && strstr(url_params, "terminate=true"); + cpa_signal->name = switch_core_strdup(pool, url_dup); + switch_core_hash_insert(component->signals, cpa_signal->name, cpa_signal); + subscribe(switch_core_session_get_uuid(session), cpa_signal->name, RAYO_JID(component)); + } else { + free(url_dup); + stop_cpa_detectors(component); + RAYO_UNLOCK(component); + RAYO_DESTROY(component); + return iks_new_error_detailed(iq, STANZA_ERROR_INTERNAL_SERVER_ERROR, error_str); + } + + free(url_dup); + } + } + + if (!have_grammar) { + stop_cpa_detectors(component); + RAYO_UNLOCK(component); + RAYO_DESTROY(component); + return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, "No grammar defined"); + } + + /* acknowledge command */ + rayo_component_send_start(RAYO_COMPONENT(component), iq); + + /* TODO hangup race condition */ + subscribe(switch_core_session_get_uuid(session), "hangup", RAYO_JID(component)); + + /* ready to forward detector events */ + component->ready = 1; + + return NULL; +} + +/** + * Load input CPA + * @param module_interface + * @param pool memory pool + * @param config_file + * @return SWITCH_STATUS_SUCCESS if successfully loaded + */ +switch_status_t rayo_cpa_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file) +{ + rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "cpa", "set:"RAYO_EXT_NS":stop", stop_cpa_component); + switch_event_bind("rayo_cpa_component", SWITCH_EVENT_CUSTOM, "rayo::cpa", on_rayo_cpa_detector_event, NULL); + switch_event_bind("rayo_cpa_component", SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE, NULL, on_channel_hangup_complete_event, NULL); + + globals.pool = pool; + switch_core_hash_init(&globals.subscribers, pool); + switch_mutex_init(&globals.subscribers_mutex, SWITCH_MUTEX_NESTED, pool); + + return rayo_cpa_detector_load(module_interface, pool, config_file); +} + +/** + * Stop input CPA + */ +void rayo_cpa_component_shutdown(void) +{ + switch_event_unbind_callback(on_rayo_cpa_detector_event); + switch_event_unbind_callback(on_channel_hangup_complete_event); + rayo_cpa_detector_shutdown(); + switch_core_hash_destroy(&globals.subscribers); +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet + */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_component.h b/src/mod/event_handlers/mod_rayo/rayo_cpa_component.h new file mode 100644 index 0000000000..36354c9508 --- /dev/null +++ b/src/mod/event_handlers/mod_rayo/rayo_cpa_component.h @@ -0,0 +1,53 @@ +/* + * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2014, Grasshopper + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is Grasshopper + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Rienzo + * + * rayo_cpa_component.h -- Rayo call progress analysis component + * + */ +#ifndef RAYO_CPA_COMPONENT_H +#define RAYO_CPA_COMPONENT_H + +#include +#include + +#include "mod_rayo.h" + +extern switch_status_t rayo_cpa_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); +extern void rayo_cpa_component_shutdown(void); +extern iks *rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data); + +#endif + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet + */ diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c index 9267e05456..27ce9a13be 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c +++ b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c @@ -155,21 +155,27 @@ static void rayo_cpa_detector_event(switch_event_t *event) } if (!zstr(signal_type)) { switch_event_t *cpa_event; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got Rayo CPA event %s\n", signal_type); + const char *uuid = switch_event_get_header(event, "Unique-ID"); + if (zstr(uuid)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s %s event is missing call UUID!\n", detector->name, signal_type); + return; + } + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got Rayo CPA event %s\n", signal_type); if (switch_event_create_subclass(&cpa_event, SWITCH_EVENT_CUSTOM, "rayo::cpa") == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "detector-name", detector->name); - switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "detector-uuid", detector->uuid); - switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "signal-type", signal_type); + switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "Unique-ID", uuid); + switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "detector-name", detector->name); + switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "detector-uuid", detector->uuid); + switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "signal-type", "%s%s:%s", RAYO_CPA_BASE, signal_type, RAYO_VERSION); if (!zstr(detector->signal_value_header)) { const char *value = switch_event_get_header(event, detector->signal_value_header); if (!zstr(value)) { - switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "value", value); + switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "value", value); } } if (!zstr(detector->signal_duration_header)) { const char *duration = switch_event_get_header(event, detector->signal_duration_header); if (!zstr(duration)) { - switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "duration", duration); + switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "duration", duration); } } switch_event_fire(&cpa_event); diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h index 335d1c3a1b..fcdc35f2f4 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h +++ b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.h @@ -33,21 +33,6 @@ #include "mod_rayo.h" -#define RAYO_CPA_BASE RAYO_BASE "cpa:" -#define RAYO_CPA_NS RAYO_CPA_BASE RAYO_VERSION - -#define RAYO_CPA_BEEP_NS RAYO_CPA_BASE "beep:" RAYO_VERSION -#define RAYO_CPA_DTMF_NS RAYO_CPA_BASE "dtmf:" RAYO_VERSION -#define RAYO_CPA_SPEECH_NS RAYO_CPA_BASE "speech:" RAYO_VERSION -#define RAYO_CPA_FAX_CED_NS RAYO_CPA_BASE "fax-ced:" RAYO_VERSION -#define RAYO_CPA_FAX_CNG_NS RAYO_CPA_BASE "fax-cng:" RAYO_VERSION -#define RAYO_CPA_RING_NS RAYO_CPA_BASE "ring:" RAYO_VERSION -#define RAYO_CPA_BUSY_NS RAYO_CPA_BASE "busy:" RAYO_VERSION -#define RAYO_CPA_CONGESTION_NS RAYO_CPA_BASE "congestion:" RAYO_VERSION -#define RAYO_CPA_SIT_NS RAYO_CPA_BASE "sit:" RAYO_VERSION -#define RAYO_CPA_MODEM_NS RAYO_CPA_BASE "modem:" RAYO_VERSION -#define RAYO_CPA_OFFHOOK_NS RAYO_CPA_BASE "offhook:" RAYO_VERSION - extern switch_status_t rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file); extern void rayo_cpa_detector_shutdown(void); extern int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail); diff --git a/src/mod/event_handlers/mod_rayo/rayo_elements.c b/src/mod/event_handlers/mod_rayo/rayo_elements.c index 78209c3bd6..1720471e31 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_elements.c +++ b/src/mod/event_handlers/mod_rayo/rayo_elements.c @@ -33,7 +33,7 @@ */ ELEMENT(RAYO_INPUT) ATTRIB(xmlns,, any) - STRING_ATTRIB(mode, any, "any,dtmf,voice") + STRING_ATTRIB(mode, any, "any,dtmf,voice,cpa") OPTIONAL_ATTRIB(terminator,, dtmf_digit) ATTRIB(recognizer,, any) ATTRIB(language, en-US, any) diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c index 4ea0e5f600..41383a1d23 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_input_component.c @@ -27,7 +27,7 @@ * */ #include "rayo_components.h" -#include "rayo_cpa_detector.h" +#include "rayo_cpa_component.h" #include "rayo_elements.h" #include "srgs.h" #include "nlsml.h" @@ -360,10 +360,14 @@ static iks *start_call_input(struct input_component *component, switch_core_sess component->speech_mode = strcmp(iks_find_attrib_soft(input, "mode"), "dtmf"); if (component->speech_mode && handler->voice_component) { /* don't allow multi voice input */ + RAYO_UNLOCK(component); + RAYO_DESTROY(component); return iks_new_error_detailed(iq, STANZA_ERROR_CONFLICT, "Multiple voice input is not allowed"); } if (!component->speech_mode && handler->dtmf_component) { /* don't allow multi dtmf input */ + RAYO_UNLOCK(component); + RAYO_DESTROY(component); return iks_new_error_detailed(iq, STANZA_ERROR_CONFLICT, "Multiple dtmf input is not allowed"); } @@ -538,17 +542,20 @@ static iks *start_call_input_component(struct rayo_actor *call, struct rayo_mess struct input_component *input_component = NULL; const char *error = NULL; + /* Start CPA */ + if (!strcmp(iks_find_attrib_soft(input, "mode"), "cpa")) { + return rayo_cpa_component_start(call, msg, session_data); + } + + /* start input */ if (!validate_call_input(input, &error)) { return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, error); } - /* create component */ switch_core_new_memory_pool(&pool); input_component = switch_core_alloc(pool, sizeof(*input_component)); rayo_component_init(RAYO_COMPONENT(input_component), pool, RAT_CALL_COMPONENT, "input", component_id, call, iks_find_attrib(iq, "from")); - - /* start input */ - return start_call_input(input_component, session, iks_find(iq, "input"), iq, NULL, 0); + return start_call_input(input_component, session, input, iq, NULL, 0); } /** @@ -761,7 +768,7 @@ switch_status_t rayo_input_component_load(switch_loadable_module_interface_t **m rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "input", "set:"RAYO_INPUT_NS":start-timers", start_timers_call_input_component); switch_event_bind("rayo_input_component", SWITCH_EVENT_DETECTED_SPEECH, SWITCH_EVENT_SUBCLASS_ANY, on_detected_speech_event, NULL); - return rayo_cpa_detector_load(module_interface, pool, config_file); + return rayo_cpa_component_load(module_interface, pool, config_file); } /** @@ -773,7 +780,7 @@ switch_status_t rayo_input_component_shutdown(void) srgs_parser_destroy(globals.parser); switch_event_unbind_callback(on_detected_speech_event); - rayo_cpa_detector_shutdown(); + rayo_cpa_component_shutdown(); return SWITCH_STATUS_SUCCESS; } From 8d30da28d7e4939ec6fd94222e7a4b43bd6b24ec Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 6 Jan 2014 09:50:28 -0500 Subject: [PATCH 234/656] mod_rayo FS-6071 fix DTMF overflow and increase max DTMF matching from 64 to 256 --- src/mod/event_handlers/mod_rayo/rayo_input_component.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_input_component.c b/src/mod/event_handlers/mod_rayo/rayo_input_component.c index 41383a1d23..72f52cb552 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_input_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_input_component.c @@ -32,7 +32,7 @@ #include "srgs.h" #include "nlsml.h" -#define MAX_DTMF 64 +#define MAX_DTMF 256 #define INPUT_MATCH_TAG "match" #define INPUT_MATCH INPUT_MATCH_TAG, RAYO_INPUT_COMPLETE_NS @@ -183,13 +183,18 @@ static switch_status_t input_component_on_dtmf(switch_core_session_t *session, c match = srgs_grammar_match(component->grammar, component->digits, &interpretation); - /* adjust result if terminating digit was pressed */ if (is_term_digit) { + /* finalize result if terminating digit was pressed */ if (match == SMT_MATCH_PARTIAL) { match = SMT_NO_MATCH; } else if (match == SMT_MATCH) { match = SMT_MATCH_END; } + } else if (component->num_digits >= MAX_DTMF) { + /* maximum digits collected and still not a definitive match */ + if (match != SMT_MATCH_END) { + match = SMT_NO_MATCH; + } } switch (match) { From 9efe980438faed517a9256411345972861e819f5 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 6 Jan 2014 14:36:47 -0500 Subject: [PATCH 235/656] mod_rayo --resolve FS-6072 fixed prompt state machine --- .../mod_rayo/rayo_prompt_component.c | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c b/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c index 7bb530fe3f..3debe39c3e 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_prompt_component.c @@ -261,17 +261,32 @@ static iks *prompt_component_handle_input_error(struct rayo_actor *prompt, struc switch (PROMPT_COMPONENT(prompt)->state) { case PCS_START_INPUT_TIMERS: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, error: %s\n", RAYO_JID(prompt), iks_string(iks_stack(iq), iq)); + PROMPT_COMPONENT(prompt)->state = PCS_DONE; + + /* forward IQ error to client */ + iq = PROMPT_COMPONENT(prompt)->iq; + iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); + iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); + iks_insert_node(iq, iks_copy_within(error, iks_stack(iq))); + RAYO_SEND_REPLY(prompt, RAYO_COMPONENT(prompt)->client_jid, iq); + + /* done */ + RAYO_UNLOCK(prompt); + RAYO_DESTROY(prompt); + + break; + case PCS_START_INPUT: - /* send error to client */ - PROMPT_COMPONENT(prompt)-> state = PCS_DONE; + /* send presence error to client */ + PROMPT_COMPONENT(prompt)->state = PCS_DONE; iks_delete(PROMPT_COMPONENT(prompt)->iq); rayo_component_send_complete(RAYO_COMPONENT(prompt), COMPONENT_COMPLETE_ERROR); break; - break; case PCS_START_INPUT_OUTPUT: PROMPT_COMPONENT(prompt)->state = PCS_DONE_STOP_OUTPUT; - /* forward error to client */ + /* forward IQ error to client */ iq = PROMPT_COMPONENT(prompt)->iq; iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); @@ -312,7 +327,7 @@ static iks *prompt_component_handle_output_error(struct rayo_actor *prompt, stru switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, error: %s\n", RAYO_JID(prompt), iks_string(iks_stack(iq), iq)); PROMPT_COMPONENT(prompt)->state = PCS_DONE; - /* forward error to client */ + /* forward IQ error to client */ iq = PROMPT_COMPONENT(prompt)->iq; iks_insert_attrib(iq, "from", RAYO_JID(RAYO_COMPONENT(prompt)->parent)); iks_insert_attrib(iq, "to", RAYO_COMPONENT(prompt)->client_jid); From 3ff0aaa0befa3ff68aa0adeac8ab062d8f9ddcb5 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 7 Jan 2014 00:38:42 +0500 Subject: [PATCH 236/656] FS-5653 --resolve --- libs/esl/fs_cli.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 05286ecc49..968e647e33 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -85,6 +85,8 @@ static int running = 1; static int thread_running = 0; static char *filter_uuid; static char *logfilter; +static int timeout = 0; +static int connect_timeout = 0; #ifndef WIN32 static EditLine *el; static History *myhistory; @@ -603,6 +605,7 @@ static const char *usage_str = " -d, --debug=level Debug Level (0 - 7)\n" " -b, --batchmode Batch mode\n" " -t, --timeout Timeout for API commands (in miliseconds)\n" + " -T, --connect-timeout Timeout for socket connection (in miliseconds)\n" " -n, --no-color Disable color\n\n"; static int usage(char *name){ @@ -1249,6 +1252,10 @@ static void read_config(const char *dft_cfile, const char *cfile) { profiles[pcount-1].console_fnkeys[i - 1] = strdup(val); } } + } else if (!strcasecmp(var, "timeout")) { + timeout = atoi(val); + } else if (!strcasecmp(var, "connect-timeout")) { + connect_timeout = atoi(val); } } esl_config_close_file(&cfg); @@ -1301,6 +1308,7 @@ int main(int argc, char *argv[]) {"interrupt", 0, 0, 'i'}, {"reconnect", 0, 0, 'R'}, {"timeout", 1, 0, 't'}, + {"connect-timeout", 1, 0, 'T'}, {0, 0, 0, 0} }; char temp_host[128]; @@ -1319,7 +1327,7 @@ int main(int argc, char *argv[]) int argv_log_uuid = 0; int argv_quiet = 0; int argv_batch = 0; - int loops = 2, reconnect = 0, timeout = 0; + int loops = 2, reconnect = 0; char *ccheck; #ifdef WIN32 @@ -1354,7 +1362,7 @@ int main(int argc, char *argv[]) esl_global_set_default_logger(6); /* default debug level to 6 (info) */ for(;;) { int option_index = 0; - opt = getopt_long(argc, argv, "H:P:S:u:p:d:x:l:Ut:qrRhib?n", options, &option_index); + opt = getopt_long(argc, argv, "H:P:S:u:p:d:x:l:Ut:T:qrRhib?n", options, &option_index); if (opt == -1) break; switch (opt) { case 'H': @@ -1418,6 +1426,9 @@ int main(int argc, char *argv[]) case 't': timeout = atoi(optarg); break; + case 'T': + connect_timeout = atoi(optarg); + break; case 'h': case '?': print_banner(stdout, is_color); @@ -1488,7 +1499,7 @@ int main(int argc, char *argv[]) connected = 0; while (--loops > 0) { memset(&handle, 0, sizeof(handle)); - if (esl_connect(&handle, profile->host, profile->port, profile->user, profile->pass)) { + if (esl_connect_timeout(&handle, profile->host, profile->port, profile->user, profile->pass, connect_timeout)) { esl_global_set_default_logger(7); esl_log(ESL_LOG_ERROR, "Error Connecting [%s]\n", handle.err); if (loops == 1) { From 695ac57e4966e16dc5a6634d68133312c9ce8ee8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 7 Jan 2014 00:47:56 +0500 Subject: [PATCH 237/656] FS-6032 --resolve --- .../applications/mod_commands/mod_commands.c | 35 ++++--------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 2b21821ccc..2767644559 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1108,7 +1108,7 @@ SWITCH_STANDARD_API(in_group_function) SWITCH_STANDARD_API(user_data_function) { - switch_xml_t x_domain, xml = NULL, x_user = NULL, x_group = NULL, x_param, x_params; + switch_xml_t x_user = NULL, x_param, x_params; int argc; char *mydata = NULL, *argv[3], *key = NULL, *type = NULL, *user, *domain, *dup_domain = NULL; char delim = ' '; @@ -1143,7 +1143,7 @@ SWITCH_STANDARD_API(user_data_function) switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "type", type); - if (key && type && switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, params) == SWITCH_STATUS_SUCCESS) { + if (key && type && switch_xml_locate_user_merged("id:number-alias", user, domain, NULL, &x_user, params) == SWITCH_STATUS_SUCCESS) { if (!strcmp(type, "attr")) { const char *attr = switch_xml_attr_soft(x_user, key); result = attr; @@ -1155,29 +1155,6 @@ SWITCH_STANDARD_API(user_data_function) elem = "variable"; } - if ((x_params = switch_xml_child(x_domain, container))) { - for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) { - const char *var = switch_xml_attr(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - - if (var && val && !strcasecmp(var, key)) { - result = val; - } - - } - } - - if (x_group && (x_params = switch_xml_child(x_group, container))) { - for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) { - const char *var = switch_xml_attr(x_param, "name"); - const char *val = switch_xml_attr(x_param, "value"); - - if (var && val && !strcasecmp(var, key)) { - result = val; - } - } - } - if ((x_params = switch_xml_child(x_user, container))) { for (x_param = switch_xml_child(x_params, elem); x_param; x_param = x_param->next) { const char *var = switch_xml_attr(x_param, "name"); @@ -1194,7 +1171,7 @@ SWITCH_STANDARD_API(user_data_function) if (result) { stream->write_function(stream, "%s", result); } - switch_xml_free(xml); + switch_xml_free(x_user); switch_safe_free(mydata); switch_safe_free(dup_domain); switch_event_destroy(¶ms); @@ -1204,7 +1181,7 @@ SWITCH_STANDARD_API(user_data_function) static switch_status_t _find_user(const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream, switch_bool_t tf) { - switch_xml_t x_domain = NULL, x_user = NULL, xml = NULL; + switch_xml_t x_user = NULL; int argc; char *mydata = NULL, *argv[3]; char *key, *user, *domain; @@ -1244,7 +1221,7 @@ static switch_status_t _find_user(const char *cmd, switch_core_session_t *sessio goto end; } - if (switch_xml_locate_user(key, user, domain, NULL, &xml, &x_domain, &x_user, NULL, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_xml_locate_user_merged(key, user, domain, NULL, &x_user, NULL) != SWITCH_STATUS_SUCCESS) { err = "can't find user"; goto end; } @@ -1274,7 +1251,7 @@ static switch_status_t _find_user(const char *cmd, switch_core_session_t *sessio } } - switch_xml_free(xml); + switch_xml_free(x_user); switch_safe_free(mydata); return SWITCH_STATUS_SUCCESS; } From f8844d1398b60e49ae1b6543fd3532c71d4f4e74 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 7 Jan 2014 01:54:31 +0500 Subject: [PATCH 238/656] FS-6020 --resolve --- src/switch_channel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_channel.c b/src/switch_channel.c index 21b9dedc6f..eb8be218d1 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1971,6 +1971,7 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch } switch_mutex_unlock(channel->profile_mutex); + switch_channel_set_callstate(channel, CCS_ACTIVE); } if (flag == CF_ORIGINATOR && switch_channel_test_flag(channel, CF_ANSWERED) && switch_channel_up_nosig(channel)) { From 587ba2ed52cba1e6a51f6aed0b5d67cd4297ae73 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Mon, 6 Jan 2014 21:06:31 -0500 Subject: [PATCH 239/656] mod_rayo FS-6081 --resolve added mixer presence with entity capabilities --- src/mod/event_handlers/mod_rayo/iks_helpers.c | 23 +++ src/mod/event_handlers/mod_rayo/iks_helpers.h | 5 +- src/mod/event_handlers/mod_rayo/mod_rayo.c | 138 ++++++++++++++++-- 3 files changed, 155 insertions(+), 11 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/iks_helpers.c b/src/mod/event_handlers/mod_rayo/iks_helpers.c index 30d9d215a5..93be6db3a2 100644 --- a/src/mod/event_handlers/mod_rayo/iks_helpers.c +++ b/src/mod/event_handlers/mod_rayo/iks_helpers.c @@ -522,6 +522,29 @@ char *iks_server_dialback_key(const char *secret, const char *receiving_server, return NULL; } +/** + * Print base 64 encoded SHA-1 hash + * @param sha hash to print + * @param buf to store baes 64 encoded hash + */ +void iks_sha_print_base64(iksha *sha, char *buf) +{ + int i; + char hex_digit[3] = { 0 }; + char hex_buf[SHA_1_HASH_BUF_SIZE]; + unsigned char bin_buf[SHA_1_HASH_BUF_SIZE / 2]; + iks_sha_print(sha, hex_buf); + + /* convert hex string to octets */ + for (i = 0; i < SHA_1_HASH_BUF_SIZE; i += 2) { + hex_digit[0] = hex_buf[i]; + hex_digit[1] = hex_buf[i + 1]; + bin_buf[i / 2] = strtol(hex_digit, NULL, 16); + } + + switch_b64_encode(bin_buf, SHA_1_HASH_BUF_SIZE / 2, (unsigned char *)buf, SHA_1_HASH_BUF_SIZE); +} + /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/event_handlers/mod_rayo/iks_helpers.h b/src/mod/event_handlers/mod_rayo/iks_helpers.h index 3a7bae02e7..2017134713 100644 --- a/src/mod/event_handlers/mod_rayo/iks_helpers.h +++ b/src/mod/event_handlers/mod_rayo/iks_helpers.h @@ -32,6 +32,8 @@ #include #include +#define SHA_1_HASH_BUF_SIZE 40 + #define IKS_JABBER_SERVER_PORT 5269 #define IKS_NS_XMPP_DISCO "http://jabber.org/protocol/disco#info" @@ -40,6 +42,7 @@ #define IKS_NS_XMPP_STREAMS "http://etherx.jabber.org/streams" #define IKS_NS_XMPP_DIALBACK "jabber:server:dialback" #define IKS_NS_XMPP_TLS "urn:ietf:params:xml:ns:xmpp-tls" +#define IKS_NS_XMPP_ENTITY_CAPABILITIES "http://jabber.org/protocol/caps" struct xmpp_error { const char *name; @@ -53,7 +56,6 @@ struct xmpp_error { #include "xmpp_errors.def" /* See RFC-3920 XMPP core for error definitions */ - extern iks *iks_new_presence(const char *name, const char *namespace, const char *from, const char *to); extern iks *iks_new_error(iks *iq, const struct xmpp_error *err); extern iks *iks_new_error_detailed(iks *iq, const struct xmpp_error *err, const char *detail_text); @@ -70,6 +72,7 @@ extern const char *iks_net_error_to_string(int err); extern iks *iks_insert_attrib_printf(iks *xml, const char *name, const char *fmt, ...); extern char *iks_server_dialback_key(const char *secret, const char *receiving_server, const char *originating_server, const char *stream_id); +extern void iks_sha_print_base64(iksha *sha, char *buf); /** A function to validate attribute value */ typedef int (*iks_attrib_validation_function)(const char *); diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 95162093c8..d88cc26af0 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -170,9 +170,9 @@ struct rayo_mixer_member { * A subscriber to mixer events */ struct rayo_mixer_subscriber { - /** JID of subscriber */ + /** JID of client */ const char *jid; - /** Number of controlled parties in mixer */ + /** Number of client's calls in mixer */ int ref_count; }; @@ -250,6 +250,54 @@ typedef switch_bool_t (* rayo_actor_match_fn)(struct rayo_actor *); static switch_bool_t is_call_actor(struct rayo_actor *actor); +/** + * Entity features returned by service discovery + */ +struct entity_identity { + /** identity category */ + const char *category; + /** identity type */ + const char *type; +}; + +static struct entity_identity rayo_server_identity = { "server", "im" }; +static const char *rayo_server_features[] = { IKS_NS_XMPP_ENTITY_CAPABILITIES, IKS_NS_XMPP_DISCO, RAYO_NS, RAYO_CPA_NS, RAYO_FAX_NS, 0 }; + +static struct entity_identity rayo_mixer_identity = { "client", "rayo_mixer" }; +static const char *rayo_mixer_features[] = { 0 }; + +static struct entity_identity rayo_call_identity = { "client", "rayo_call" }; +static const char *rayo_call_features[] = { 0 }; + +/** + * Calculate SHA-1 hash of entity capabilities + * @param identity of entity + * @param features of identity (NULL terminated) + * @return base64 hash (free when done) + */ +static char *calculate_entity_sha1_ver(struct entity_identity *identity, const char **features) +{ + int i; + const char *feature; + char ver[SHA_1_HASH_BUF_SIZE + 1] = { 0 }; + iksha *sha; + + sha = iks_sha_new(); + iks_sha_hash(sha, (const unsigned char *)identity->category, strlen(identity->category), 0); + iks_sha_hash(sha, (const unsigned char *)"/", 1, 0); + iks_sha_hash(sha, (const unsigned char *)identity->type, strlen(identity->type), 0); + iks_sha_hash(sha, (const unsigned char *)"//", 2, 0); + i = 0; + while ((feature = features[i++])) { + iks_sha_hash(sha, (const unsigned char *)"<", 1, 0); + iks_sha_hash(sha, (const unsigned char *)feature, strlen(feature), 0); + } + iks_sha_hash(sha, (const unsigned char *)"<", 1, 1); + iks_sha_print_base64(sha, ver); + iks_sha_delete(sha); + + return strdup(ver); +} /** * @param msg to check @@ -408,6 +456,32 @@ static void add_header(iks *node, const char *name, const char *value) } } +/** + * Send event to clients + * @param from event sender + * @param rayo_event the event to send + * @param online_only only send to online clients + */ +static void broadcast_event(struct rayo_actor *from, iks *rayo_event, int online_only) +{ + switch_hash_index_t *hi = NULL; + switch_mutex_lock(globals.clients_mutex); + for (hi = switch_hash_first(NULL, globals.clients_roster); hi; hi = switch_hash_next(hi)) { + struct rayo_client *rclient; + const void *key; + void *val; + switch_hash_this(hi, &key, NULL, &val); + rclient = (struct rayo_client *)val; + switch_assert(rclient); + + if (!online_only || rclient->availability == PS_ONLINE) { + iks_insert_attrib(rayo_event, "to", RAYO_JID(rclient)); + RAYO_SEND_MESSAGE_DUP(from, RAYO_JID(rclient), rayo_event); + } + } + switch_mutex_unlock(globals.clients_mutex); +} + /** * Add an outbound dialing gateway * @param uri_prefix to match @@ -2445,15 +2519,20 @@ static iks *on_iq_get_xmpp_disco(struct rayo_actor *server, struct rayo_message iks *response = NULL; iks *x; iks *feature; + iks *identity; + int i = 0; + const char *feature_string; response = iks_new_iq_result(node); x = iks_insert(response, "query"); iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_DISCO); - feature = iks_insert(x, "feature"); - iks_insert_attrib(feature, "var", RAYO_NS); - feature = iks_insert(x, "feature"); - iks_insert_attrib(feature, "var", RAYO_CPA_NS); - feature = iks_insert(x, "feature"); - iks_insert_attrib(feature, "var", RAYO_FAX_NS); + identity = iks_insert(x, "identity"); + iks_insert_attrib(identity, "category", rayo_server_identity.category); + iks_insert_attrib(identity, "type", rayo_server_identity.type); + i = 0; + while((feature_string = rayo_server_features[i++])) { + feature = iks_insert(x, "feature"); + iks_insert_attrib(feature, "var", feature_string); + } /* TODO The response MUST also include features for the application formats and transport methods supported by * the responding entity, as described in the relevant specifications. @@ -2669,6 +2748,15 @@ static void on_mixer_delete_member_event(struct rayo_mixer *mixer, switch_event_ static void on_mixer_destroy_event(struct rayo_mixer *mixer, switch_event_t *event) { if (mixer) { + iks *presence; + + /* notify online clients of mixer destruction */ + presence = iks_new("presence"); + iks_insert_attrib(presence, "from", RAYO_JID(mixer)); + iks_insert_attrib(presence, "type", "unavailable"); + broadcast_event(RAYO_ACTOR(mixer), presence, 1); + iks_delete(presence); + /* remove from hash and destroy */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s, destroying mixer: %s\n", RAYO_JID(mixer), rayo_mixer_get_name(mixer)); RAYO_UNLOCK(mixer); /* release original lock */ @@ -2688,10 +2776,25 @@ static void on_mixer_add_member_event(struct rayo_mixer *mixer, switch_event_t * struct rayo_call *call = RAYO_CALL_LOCATE_BY_ID(uuid); if (!mixer) { + char *ver; + iks *presence, *c; + /* new mixer */ const char *mixer_name = switch_event_get_header(event, "Conference-Name"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "creating mixer: %s\n", mixer_name); mixer = rayo_mixer_create(mixer_name); + + /* notify online clients of mixer presence */ + ver = calculate_entity_sha1_ver(&rayo_mixer_identity, rayo_mixer_features); + + presence = iks_new_presence("c", IKS_NS_XMPP_ENTITY_CAPABILITIES, RAYO_JID(mixer), ""); + c = iks_find(presence, "c"); + iks_insert_attrib(c, "hash", "sha-1"); + iks_insert_attrib(c, "node", RAYO_MIXER_NS); + iks_insert_attrib(c, "ver", ver); + free(ver); + + broadcast_event(RAYO_ACTOR(mixer), presence, 1); } if (call) { @@ -2719,6 +2822,9 @@ static void on_mixer_add_member_event(struct rayo_mixer *mixer, switch_event_t * if (call->pending_join_request) { iks *request = call->pending_join_request; iks *result = iks_new_iq_result(request); + iks *ref = iks_insert(result, "ref"); + iks_insert_attrib(ref, "xmlns", RAYO_NS); + iks_insert_attrib_printf(ref, "uri", "xmpp:%s", RAYO_JID(mixer)); call->pending_join_request = NULL; RAYO_SEND_REPLY(call, iks_find_attrib_soft(request, "from"), result); iks_delete(request); @@ -3135,12 +3241,24 @@ static iks *rayo_create_offer(struct rayo_call *call, switch_core_session_t *ses switch_channel_t *channel = switch_core_session_get_channel(session); switch_caller_profile_t *profile = switch_channel_get_caller_profile(channel); iks *presence = iks_new("presence"); + iks *c = iks_insert(presence, "c"); iks *offer = iks_insert(presence, "offer"); const char *val; + char *ver; + /* */ iks_insert_attrib(presence, "from", RAYO_JID(call)); - iks_insert_attrib(offer, "xmlns", RAYO_NS); + /* */ + ver = calculate_entity_sha1_ver(&rayo_call_identity, rayo_call_features); + iks_insert_attrib(c, "xmlns", IKS_NS_XMPP_ENTITY_CAPABILITIES); + iks_insert_attrib(c, "hash", "sha-1"); + iks_insert_attrib(c, "node", RAYO_CALL_NS); + iks_insert_attrib(c, "ver", ver); + free(ver); + + /* */ + iks_insert_attrib(offer, "xmlns", RAYO_NS); if (globals.offer_uri && (val = switch_channel_get_variable(channel, "sip_from_uri"))) { /* is a SIP call - pass the URI */ if (!strchr(val, ':')) { @@ -3287,8 +3405,8 @@ SWITCH_STANDARD_APP(rayo_app) RAYO_SEND_MESSAGE_DUP(call, RAYO_JID(rclient), offer); } } - iks_delete(offer); switch_mutex_unlock(globals.clients_mutex); + iks_delete(offer); /* nobody to offer to */ if (!ok) { From 5b2799284b1c7dc1cec3ca33e780497a344bec4f Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 7 Jan 2014 10:10:50 -0500 Subject: [PATCH 240/656] mod_rayo CPA dtmf detection added --- conf/rayo/autoload_configs/rayo.conf.xml | 7 +++++++ .../mod_rayo/conf/autoload_configs/rayo.conf.xml | 7 +++++++ .../event_handlers/mod_rayo/rayo_cpa_detector.c | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index 52a1a35977..50af0f7ecd 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -26,6 +26,13 @@ + + + + + + + diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index 52a1a35977..50af0f7ecd 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -26,6 +26,13 @@ + + + + + + + diff --git a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c index 27ce9a13be..ed1d87d152 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c +++ b/src/mod/event_handlers/mod_rayo/rayo_cpa_detector.c @@ -79,8 +79,13 @@ struct rayo_cpa_detector_state { int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail) { struct rayo_cpa_detector *detector = switch_core_hash_find(globals.detectors, signal_ns); + switch_core_session_t *session; if (detector) { - switch_core_session_t *session = switch_core_session_locate(call_uuid); + if (zstr(detector->start_app)) { + /* nothing to do */ + return 1; + } + session = switch_core_session_locate(call_uuid); if (session) { struct rayo_cpa_detector_state *detector_state = switch_channel_get_private(switch_core_session_get_channel(session), detector->uuid); if (detector_state) { @@ -114,8 +119,13 @@ int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const void rayo_cpa_detector_stop(const char *call_uuid, const char *signal_ns) { struct rayo_cpa_detector *detector = switch_core_hash_find(globals.detectors, signal_ns); + switch_core_session_t *session; if (detector) { - switch_core_session_t *session = switch_core_session_locate(call_uuid); + if (zstr(detector->stop_app)) { + /* nothing to do */ + return; + } + session = switch_core_session_locate(call_uuid); if (session) { struct rayo_cpa_detector_state *detector_state = switch_channel_get_private(switch_core_session_get_channel(session), detector->uuid); if (detector_state) { From 7e71d85550344a0955fc6d78d53b4af7be84b743 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 7 Jan 2014 14:07:49 -0500 Subject: [PATCH 241/656] FS-6083 --resolve SSML will pass through when renderer is specified --- .../mod_rayo/rayo_output_component.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_output_component.c b/src/mod/event_handlers/mod_rayo/rayo_output_component.c index e092ebd046..3432bcefbf 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_output_component.c +++ b/src/mod/event_handlers/mod_rayo/rayo_output_component.c @@ -47,6 +47,8 @@ struct output_component { switch_bool_t start_paused; /** true if stopped */ int stop; + /** output renderer to use */ + const char *renderer; }; #define OUTPUT_FINISH "finish", RAYO_OUTPUT_COMPLETE_NS @@ -71,6 +73,7 @@ static struct rayo_component *create_output_component(struct rayo_actor *actor, output_component->repeat_times = iks_find_int_attrib(output, "repeat-times"); output_component->max_time = iks_find_int_attrib(output, "max-time"); output_component->start_paused = iks_find_bool_attrib(output, "start-paused"); + output_component->renderer = iks_find_attrib(output, "renderer"); return (struct rayo_component *)output_component; } @@ -402,7 +405,13 @@ static switch_status_t next_file(switch_file_handle_t *handle) if (speak) { /* is child node */ char *ssml_str = iks_string(NULL, speak); - context->ssml = switch_mprintf("ssml://%s", ssml_str); + if (zstr(output->renderer)) { + /* FS must parse the SSML */ + context->ssml = switch_mprintf("ssml://%s", ssml_str); + } else { + /* renderer will parse the SSML */ + context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); + } iks_free(ssml_str); } else if (iks_has_children(context->cur_doc)) { /* check if is in CDATA */ @@ -415,7 +424,13 @@ static switch_status_t next_file(switch_file_handle_t *handle) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing CDATA\n"); return SWITCH_STATUS_FALSE; } - context->ssml = switch_mprintf("ssml://%s", ssml_str); + if (zstr(output->renderer)) { + /* FS must parse the SSML */ + context->ssml = switch_mprintf("ssml://%s", ssml_str); + } else { + /* renderer will parse the SSML */ + context->ssml = switch_mprintf("tts://%s||%s", output->renderer, ssml_str); + } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing \n"); return SWITCH_STATUS_FALSE; From d25d1293bcd930b9763c4961c78676b805c95d81 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 7 Jan 2014 14:50:14 -0500 Subject: [PATCH 242/656] FS-6083 --resolve mod_ssml fixed --- src/mod/formats/mod_ssml/mod_ssml.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/mod/formats/mod_ssml/mod_ssml.c b/src/mod/formats/mod_ssml/mod_ssml.c index 8b172721c7..ae2670a74c 100644 --- a/src/mod/formats/mod_ssml/mod_ssml.c +++ b/src/mod/formats/mod_ssml/mod_ssml.c @@ -259,17 +259,6 @@ static int process_tag(struct ssml_parser *parser, const char *name, char **atts return IKS_BADXML; } -/** - * Handle tag attributes that are ignored - * @param parser the parser - * @param atts the attributes - * @return IKS_OK - */ -static int process_attribs_ignore(struct ssml_parser *parser, char **atts) -{ - return IKS_OK; -} - /** * Handle CDATA that is ignored * @param parser the parser @@ -395,6 +384,19 @@ static struct voice *find_say_voice(struct ssml_node *cur_node) return find_voice(cur_node, globals.say_voice_map, "say", 1); } +/** + * Handle tag attributes that are ignored + * @param parser the parser + * @param atts the attributes + * @return IKS_OK + */ +static int process_attribs_ignore(struct ssml_parser *parsed_data, char **atts) +{ + struct ssml_node *cur_node = parsed_data->cur_node; + cur_node->tts_voice = find_tts_voice(cur_node); + return IKS_OK; +} + /** * open next file for reading * @param handle the file handle From af0c6308f561767cbb0ca2ee4259daf2b0c26cdb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 8 Jan 2014 04:12:01 +0500 Subject: [PATCH 243/656] allow native recording and transcoding at the same time --- src/switch_core_io.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_core_io.c b/src/switch_core_io.c index d571da41b0..c07a428e3c 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -360,6 +360,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi if (session->read_codec->implementation->impl_id != codec_impl.impl_id) { need_codec = TRUE; + tap_only = 0; } if (codec_impl.actual_samples_per_second != session->read_impl.actual_samples_per_second) { From b9b9f6fe7c58e014a5fa3d9c963b7977ceb6aff1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 8 Jan 2014 21:12:19 +0000 Subject: [PATCH 244/656] Drop mod_spidermonkey from our default build There are build issues with mod_spidermonkey on certain platforms, and we hope to replace it soon anyway. --- build/modules.conf.in | 2 +- conf/vanilla/autoload_configs/modules.conf.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/modules.conf.in b/build/modules.conf.in index f7b36831cc..b4c6f70888 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -118,7 +118,7 @@ languages/mod_lua #languages/mod_managed #languages/mod_perl #languages/mod_python -languages/mod_spidermonkey +#languages/mod_spidermonkey #languages/mod_yaml loggers/mod_console loggers/mod_logfile diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 0ca6bc5b34..27fde61a64 100644 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -109,7 +109,7 @@ - + From 396ccaff516fa8a62895b807a828e133f7f9371d Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 7 Jan 2014 22:50:28 +0000 Subject: [PATCH 245/656] Prevent -lfoo lib flags from becoming dependencies Previously we were including the output of `apr-1-config/apu-1-config --libs` into CORE_LIBS. This seemed sensible as CORE_LIBS is added in the right places to various _LDADD and _LIBADD variables. However we also use the value of CORE_LIBS as dependencies in the makefile. Astonishingly this doesn't seem to cause any issues on most platforms (or we would have noticed sooner), but it does break things on Mac. Thanks-to: Seven Du FS-5956 --resolve --- Makefile.am | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 1c762ac264..a47000bf5c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,10 +6,10 @@ NAME = freeswitch AM_LIBAPR_CFLAGS := $(shell ./libs/apr/apr-1-config --cflags) AM_LIBAPR_CPPFLAGS := $(shell ./libs/apr/apr-1-config --cppflags --includes) AM_LIBAPR_LDFLAGS := $(shell ./libs/apr/apr-1-config --ldflags) -AM_LIBAPR_LIBS := $(subst $(switch_srcdir)/,,$(shell ./libs/apr/apr-1-config \--link-libtool \--libs)) +AM_LIBAPR_LIBS := $(subst $(switch_srcdir)/,,$(shell ./libs/apr/apr-1-config \--libs)) AM_LIBAPU_CPPFLAGS := $(shell ./libs/apr-util/apu-1-config --includes) AM_LIBAPU_LDFLAGS := $(shell ./libs/apr-util/apu-1-config --ldflags) -AM_LIBAPU_LIBS := $(subst $(switch_srcdir)/,,$(shell ./libs/apr-util/apu-1-config \--link-libtool \--libs)) +AM_LIBAPU_LIBS := $(subst $(switch_srcdir)/,,$(shell ./libs/apr-util/apu-1-config \--libs)) AM_CFLAGS = $(SWITCH_AM_CFLAGS) $(SWITCH_ANSI_CFLAGS) AM_CPPFLAGS = $(SWITCH_AM_CXXFLAGS) -Ilibs/sofia-sip/libsofia-sip-ua/sdp -Ilibs/sofia-sip/libsofia-sip-ua/su @@ -120,7 +120,8 @@ CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/include CORE_CFLAGS += -I$(switch_srcdir)/libs/srtp/crypto/include -Ilibs/srtp/crypto/include CORE_CFLAGS += -I$(switch_srcdir)/libs/spandsp/src -I$(switch_srcdir)/libs/tiff-4.0.2/libtiff -CORE_LIBS = $(AM_LIBAPU_LIBS) $(AM_LIBAPR_LIBS) +APR_LIBS = $(AM_LIBAPU_LIBS) $(AM_LIBAPR_LIBS) +CORE_LIBS = libs/apr-util/libaprutil-1.la libs/apr/libapr-1.la CORE_LIBS += libs/sqlite/libsqlite3.la libs/pcre/libpcre.la libs/speex/libspeex/libspeexdsp.la if ENABLE_SRTP @@ -155,7 +156,7 @@ endif lib_LTLIBRARIES = libfreeswitch.la libfreeswitch_la_CFLAGS = $(CORE_CFLAGS) $(AM_CFLAGS) libfreeswitch_la_LDFLAGS = -version-info 1:0:0 $(AM_LDFLAGS) $(PLATFORM_CORE_LDFLAGS) -libfreeswitch_la_LIBADD = $(CORE_LIBS) $(PLATFORM_CORE_LIBS) +libfreeswitch_la_LIBADD = $(CORE_LIBS) $(APR_LIBS) $(PLATFORM_CORE_LIBS) libfreeswitch_la_DEPENDENCIES = $(BUILT_SOURCES) if HAVE_ODBC @@ -342,7 +343,7 @@ endif fs_encode_SOURCES = src/fs_encode.c fs_encode_CFLAGS = $(AM_CFLAGS) fs_encode_LDFLAGS = $(AM_LDFLAGS) -fs_encode_LDADD = libfreeswitch.la $(CORE_LIBS) +fs_encode_LDADD = libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) if HAVE_ODBC fs_encode_LDADD += $(ODBC_LIB_FLAGS) @@ -355,7 +356,7 @@ endif tone2wav_SOURCES = src/tone2wav.c tone2wav_CFLAGS = $(AM_CFLAGS) tone2wav_LDFLAGS = $(AM_LDFLAGS) -tone2wav_LDADD = libfreeswitch.la $(CORE_LIBS) +tone2wav_LDADD = libfreeswitch.la $(CORE_LIBS) $(APR_LIBS) if HAVE_ODBC tone2wav_LDADD += $(ODBC_LIB_FLAGS) From 2cb5f430b20a76451c89cc731ff0e8ad775f7ea0 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 8 Jan 2014 04:20:42 -0500 Subject: [PATCH 246/656] mod_spandsp added stopfax APP --- src/mod/applications/mod_spandsp/mod_spandsp.c | 6 ++++++ src/mod/applications/mod_spandsp/mod_spandsp.h | 1 + src/mod/applications/mod_spandsp/mod_spandsp_fax.c | 12 +++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index b6ff1771de..08bcf5e17d 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -64,6 +64,11 @@ SWITCH_STANDARD_APP(spanfax_rx_function) mod_spandsp_fax_process_fax(session, data, FUNCTION_RX); } +SWITCH_STANDARD_APP(spanfax_stop_function) +{ + mod_spandsp_fax_stop_fax(session); +} + SWITCH_STANDARD_APP(dtmf_session_function) { spandsp_inband_dtmf_session(session); @@ -740,6 +745,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spandsp_init) SAF_SUPPORT_NOMEDIA | SAF_NO_LOOPBACK); SWITCH_ADD_APP(app_interface, "txfax", "FAX Transmit Application", "FAX Transmit Application", spanfax_tx_function, SPANFAX_TX_USAGE, SAF_SUPPORT_NOMEDIA | SAF_NO_LOOPBACK); + SWITCH_ADD_APP(app_interface, "stopfax", "Stop FAX Application", "Stop FAX Application", spanfax_stop_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "spandsp_stop_dtmf", "stop inband dtmf", "Stop detecting inband dtmf.", stop_dtmf_session_function, "", SAF_NONE); SWITCH_ADD_APP(app_interface, "spandsp_start_dtmf", "Detect dtmf", "Detect inband dtmf on the session", dtmf_session_function, "", SAF_MEDIA_TAP); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.h b/src/mod/applications/mod_spandsp/mod_spandsp.h index 5f5a038c43..ac40fa2d9b 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.h +++ b/src/mod/applications/mod_spandsp/mod_spandsp.h @@ -132,6 +132,7 @@ void mod_spandsp_dsp_shutdown(void); void mod_spandsp_fax_event_handler(switch_event_t *event); void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *data, mod_spandsp_fax_application_mode_t app_mode); +void mod_spandsp_fax_stop_fax(switch_core_session_t *session); switch_bool_t t38_gateway_start(switch_core_session_t *session, const char *app, const char *data); switch_status_t spandsp_stop_inband_dtmf_session(switch_core_session_t *session); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index c76fda6637..026917b58f 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -1347,6 +1347,14 @@ static pvt_t *pvt_init(switch_core_session_t *session, mod_spandsp_fax_applicati return pvt; } +void mod_spandsp_fax_stop_fax(switch_core_session_t *session) +{ + pvt_t *pvt = switch_channel_get_private(switch_core_session_get_channel(session), "_fax_pvt"); + if (pvt) { + pvt->done = 1; + } +} + void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *data, mod_spandsp_fax_application_mode_t app_mode) { pvt_t *pvt; @@ -1365,7 +1373,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat pvt = pvt_init(session, app_mode); - + switch_channel_set_private(channel, "_fax_pvt", pvt); buf = switch_core_session_alloc(session, SWITCH_RECOMMENDED_BUFFER_SIZE); @@ -1478,6 +1486,8 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat int tx = 0; switch_status_t status; + switch_ivr_parse_all_events(session); + /* if we are in T.38 mode, we should: 1- initialize the ptv->t38_state stuff, if not done and then set some callbacks when reading frames. From 32bbe11d6b9a74533aa730c65fa46654beee546b Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 8 Jan 2014 04:28:14 -0500 Subject: [PATCH 247/656] mod_rayo remove hack for stopping fax --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 10 ---------- src/mod/event_handlers/mod_rayo/rayo_fax_components.c | 7 ++----- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index d88cc26af0..9898191c70 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -3320,16 +3320,6 @@ static switch_status_t rayo_call_on_read_frame(switch_core_session_t *session, s switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Ending abandoned call. idle_duration_ms = %i ms\n", idle_duration_ms); switch_channel_hangup(channel, RAYO_CAUSE_HANGUP); } - - /* check for break request */ - { - const char *break_jid = switch_channel_get_variable(channel, "rayo_read_frame_interrupt"); - struct rayo_actor *actor; - if (break_jid && (actor = RAYO_LOCATE(break_jid))) { - RAYO_UNLOCK(actor); - return SWITCH_STATUS_FALSE; - } - } } return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c index bce34dc9d9..4a4fc76f6b 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c @@ -206,7 +206,6 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "txfax"); switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", fax_document); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); } @@ -309,7 +308,6 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "call-command", "execute"); switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-name", "rxfax"); switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", receivefax_component->local_filename); - switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); if (!switch_channel_test_flag(channel, CF_PROXY_MODE)) { switch_channel_set_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); } @@ -341,12 +339,11 @@ static iks *stop_fax_component(struct rayo_actor *component, struct rayo_message { iks *iq = msg->payload; switch_core_session_t *session = switch_core_session_locate(RAYO_COMPONENT(component)->parent->id); + FAX_COMPONENT(component)->stop = 1; if (session) { - /* fail on read frame until component is destroyed */ - switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", RAYO_JID(component)); + switch_core_session_execute_application_async(session, "stopfax", ""); switch_core_session_rwunlock(session); } - FAX_COMPONENT(component)->stop = 1; return iks_new_iq_result(iq); } From 35b0692c5a7c9a94f8e35d3db2d09cb41f936532 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 9 Jan 2014 14:51:20 +0000 Subject: [PATCH 248/656] Add script for build testing patches This is intended to make it easier to describe to users on JIRA how they should test build patches in a standardized manner and how to collect a full build log that includes the exact git commit they are building. --- build/build_patch.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 build/build_patch.sh diff --git a/build/build_patch.sh b/build/build_patch.sh new file mode 100755 index 0000000000..fc91b00e2f --- /dev/null +++ b/build/build_patch.sh @@ -0,0 +1,44 @@ +#!/bin/bash +set -e -o pipefail + +usage () { + printf "usage: %s [-u ] [-r ] [ ...]\n" "$0" >&2 +} + +err () { + printf "error: %s\n" "$1" >&2 + exit 1 +} + +remote=origin +ref=origin/master +dopull=true +while getopts "hnr:u:" o; do + case "$o" in + h) usage; exit 0 ;; + n) dopull=false ;; + r) ref="$OPTARG" ;; + u) remote="$OPTARG" ;; + esac +done +shift $(($OPTIND-1)) + +if ! which git >/dev/null; then + printf "error: please install git\n">&2 + exit 1; fi +if ! which wget >/dev/null; then + printf "error: please install wget\n">&2 + exit 1; fi + +now=$(date -u +%Y%m%dT%H%M%SZ) +git clean -fdx || err "failed" +git reset --hard "$ref" \ + || err "reset failed" +$dopull && (git pull "$remote" || err "failed to pull") +for patch in "$@"; do + wget -O - "$patch" | git am +done +printf '# Building FreeSWITCH %s\n' "$(git describe HEAD)" \ + > ${now}-fsbuild.log +(./bootstrap.sh && ./configure -C && make VERBOSE=1) 2>&1 \ + | tee -a ${now}-fsbuild.log From 3eb645a336b4b7137551ad1ba6e29cc4f511feb5 Mon Sep 17 00:00:00 2001 From: Raymond Chandler Date: Thu, 9 Jan 2014 14:30:41 -0500 Subject: [PATCH 249/656] FS-6093 --resolve --- src/mod/endpoints/mod_sofia/mod_sofia.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 5e27ccc864..59b7a6102e 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4967,17 +4967,17 @@ static void general_event_handler(switch_event_t *event) sofia_profile_t *profile; nua_handle_t *nh; - if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile %s\n", profile_name); - return; - } - if (ct && user && host) { char *id = NULL; char *contact, *p; switch_console_callback_match_t *list = NULL; switch_console_callback_match_node_t *m; + if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile %s\n", profile_name); + return; + } + if (!(list = sofia_reg_find_reg_url_multi(profile, user, host))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find registered user %s@%s\n", user, host); return; From 2643ac2b96c891b0827391a506f44c6cfea84378 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Jan 2014 01:25:45 +0500 Subject: [PATCH 250/656] add legacy subdir for mods with 5.1 edition of mod_lua, change languages/mod_lua to legacy/languages/mod_lua in modules.conf to use older lua mod --- build/swigall.sh | 5 + configure.in | 1 + src/mod/legacy/languages/mod_lua/Makefile.am | 35 + src/mod/legacy/languages/mod_lua/Makefile.in | 755 ++ src/mod/legacy/languages/mod_lua/freeswitch.i | 100 + .../languages/mod_lua/freeswitch_lua.cpp | 457 + .../legacy/languages/mod_lua/freeswitch_lua.h | 71 + src/mod/legacy/languages/mod_lua/hack.diff | 38 + src/mod/legacy/languages/mod_lua/lua-mode.el | 1338 +++ src/mod/legacy/languages/mod_lua/lua/Makefile | 182 + src/mod/legacy/languages/mod_lua/lua/lapi.c | 1087 +++ src/mod/legacy/languages/mod_lua/lua/lapi.h | 16 + .../legacy/languages/mod_lua/lua/lauxlib.c | 652 ++ .../legacy/languages/mod_lua/lua/lauxlib.h | 174 + .../legacy/languages/mod_lua/lua/lbaselib.c | 653 ++ src/mod/legacy/languages/mod_lua/lua/lcode.c | 839 ++ src/mod/legacy/languages/mod_lua/lua/lcode.h | 76 + src/mod/legacy/languages/mod_lua/lua/ldblib.c | 397 + src/mod/legacy/languages/mod_lua/lua/ldebug.c | 638 ++ src/mod/legacy/languages/mod_lua/lua/ldebug.h | 33 + src/mod/legacy/languages/mod_lua/lua/ldo.c | 518 + src/mod/legacy/languages/mod_lua/lua/ldo.h | 57 + src/mod/legacy/languages/mod_lua/lua/ldump.c | 164 + src/mod/legacy/languages/mod_lua/lua/lfunc.c | 174 + src/mod/legacy/languages/mod_lua/lua/lfunc.h | 34 + src/mod/legacy/languages/mod_lua/lua/lgc.c | 711 ++ src/mod/legacy/languages/mod_lua/lua/lgc.h | 110 + src/mod/legacy/languages/mod_lua/lua/linit.c | 38 + src/mod/legacy/languages/mod_lua/lua/liolib.c | 553 ++ src/mod/legacy/languages/mod_lua/lua/llex.c | 461 + src/mod/legacy/languages/mod_lua/lua/llex.h | 81 + .../legacy/languages/mod_lua/lua/llimits.h | 128 + .../legacy/languages/mod_lua/lua/lmathlib.c | 263 + src/mod/legacy/languages/mod_lua/lua/lmem.c | 86 + src/mod/legacy/languages/mod_lua/lua/lmem.h | 49 + .../legacy/languages/mod_lua/lua/loadlib.c | 666 ++ .../legacy/languages/mod_lua/lua/lobject.c | 214 + .../legacy/languages/mod_lua/lua/lobject.h | 381 + .../legacy/languages/mod_lua/lua/lopcodes.c | 102 + .../legacy/languages/mod_lua/lua/lopcodes.h | 268 + src/mod/legacy/languages/mod_lua/lua/loslib.c | 243 + .../legacy/languages/mod_lua/lua/lparser.c | 1339 +++ .../legacy/languages/mod_lua/lua/lparser.h | 82 + src/mod/legacy/languages/mod_lua/lua/lstate.c | 214 + src/mod/legacy/languages/mod_lua/lua/lstate.h | 169 + .../legacy/languages/mod_lua/lua/lstring.c | 111 + .../legacy/languages/mod_lua/lua/lstring.h | 31 + .../legacy/languages/mod_lua/lua/lstrlib.c | 869 ++ src/mod/legacy/languages/mod_lua/lua/ltable.c | 588 ++ src/mod/legacy/languages/mod_lua/lua/ltable.h | 40 + .../legacy/languages/mod_lua/lua/ltablib.c | 287 + src/mod/legacy/languages/mod_lua/lua/ltm.c | 75 + src/mod/legacy/languages/mod_lua/lua/ltm.h | 54 + .../languages/mod_lua/lua/lua.2005.vcproj | 383 + .../languages/mod_lua/lua/lua.2008.vcproj | 531 ++ .../languages/mod_lua/lua/lua.2010.vcxproj | 187 + .../languages/mod_lua/lua/lua.2012.vcxproj | 191 + src/mod/legacy/languages/mod_lua/lua/lua.c | 392 + src/mod/legacy/languages/mod_lua/lua/lua.def | 84 + src/mod/legacy/languages/mod_lua/lua/lua.h | 388 + src/mod/legacy/languages/mod_lua/lua/luac.c | 200 + .../legacy/languages/mod_lua/lua/luaconf.h | 766 ++ src/mod/legacy/languages/mod_lua/lua/lualib.h | 53 + .../legacy/languages/mod_lua/lua/lundump.c | 227 + .../legacy/languages/mod_lua/lua/lundump.h | 36 + src/mod/legacy/languages/mod_lua/lua/lvm.c | 763 ++ src/mod/legacy/languages/mod_lua/lua/lvm.h | 36 + src/mod/legacy/languages/mod_lua/lua/lzio.c | 82 + src/mod/legacy/languages/mod_lua/lua/lzio.h | 67 + src/mod/legacy/languages/mod_lua/lua/print.c | 227 + .../languages/mod_lua/mod_lua.2008.vcproj | 337 + .../languages/mod_lua/mod_lua.2010.vcxproj | 156 + .../languages/mod_lua/mod_lua.2012.vcxproj | 160 + src/mod/legacy/languages/mod_lua/mod_lua.cpp | 713 ++ src/mod/legacy/languages/mod_lua/mod_lua.log | 6 + .../legacy/languages/mod_lua/mod_lua.vcproj | 184 + .../legacy/languages/mod_lua/mod_lua_extra.c | 32 + .../legacy/languages/mod_lua/mod_lua_extra.h | 10 + .../legacy/languages/mod_lua/mod_lua_wrap.cpp | 8374 +++++++++++++++++ .../languages/mod_lua/my_swigable_cpp.h | 196 + 80 files changed, 31488 insertions(+) create mode 100644 src/mod/legacy/languages/mod_lua/Makefile.am create mode 100644 src/mod/legacy/languages/mod_lua/Makefile.in create mode 100644 src/mod/legacy/languages/mod_lua/freeswitch.i create mode 100644 src/mod/legacy/languages/mod_lua/freeswitch_lua.cpp create mode 100644 src/mod/legacy/languages/mod_lua/freeswitch_lua.h create mode 100644 src/mod/legacy/languages/mod_lua/hack.diff create mode 100644 src/mod/legacy/languages/mod_lua/lua-mode.el create mode 100644 src/mod/legacy/languages/mod_lua/lua/Makefile create mode 100644 src/mod/legacy/languages/mod_lua/lua/lapi.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lapi.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lauxlib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lauxlib.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lbaselib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lcode.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lcode.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/ldblib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/ldebug.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/ldebug.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/ldo.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/ldo.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/ldump.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lfunc.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lfunc.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lgc.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lgc.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/linit.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/liolib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/llex.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/llex.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/llimits.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lmathlib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lmem.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lmem.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/loadlib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lobject.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lobject.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lopcodes.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lopcodes.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/loslib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lparser.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lparser.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lstate.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lstate.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lstring.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lstring.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lstrlib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/ltable.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/ltable.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/ltablib.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/ltm.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/ltm.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lua.2005.vcproj create mode 100644 src/mod/legacy/languages/mod_lua/lua/lua.2008.vcproj create mode 100644 src/mod/legacy/languages/mod_lua/lua/lua.2010.vcxproj create mode 100644 src/mod/legacy/languages/mod_lua/lua/lua.2012.vcxproj create mode 100644 src/mod/legacy/languages/mod_lua/lua/lua.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lua.def create mode 100644 src/mod/legacy/languages/mod_lua/lua/lua.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/luac.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/luaconf.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lualib.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lundump.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lundump.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lvm.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lvm.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/lzio.c create mode 100644 src/mod/legacy/languages/mod_lua/lua/lzio.h create mode 100644 src/mod/legacy/languages/mod_lua/lua/print.c create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua.2008.vcproj create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua.2010.vcxproj create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua.2012.vcxproj create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua.cpp create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua.log create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua.vcproj create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua_extra.c create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua_extra.h create mode 100644 src/mod/legacy/languages/mod_lua/mod_lua_wrap.cpp create mode 100644 src/mod/legacy/languages/mod_lua/my_swigable_cpp.h diff --git a/build/swigall.sh b/build/swigall.sh index 0525faf073..04bd51088d 100755 --- a/build/swigall.sh +++ b/build/swigall.sh @@ -3,6 +3,11 @@ make swigclean make lua_wrap cd ../../../.. +cd src/mod/legacy/languages/mod_lua +make swigclean +make lua_wrap +cd ../../../.. + cd src/mod/languages/mod_perl make swigclean make mod_perl_wrap.cpp diff --git a/configure.in b/configure.in index e27d3d860a..0b1cba9b94 100644 --- a/configure.in +++ b/configure.in @@ -1159,6 +1159,7 @@ AC_CONFIG_FILES([Makefile src/mod/asr_tts/mod_unimrcp/Makefile src/mod/languages/mod_java/Makefile src/mod/languages/mod_lua/Makefile + src/mod/legacy/languages/mod_lua/Makefile src/mod/languages/mod_python/Makefile src/mod/languages/mod_spidermonkey/Makefile src/mod/event_handlers/mod_erlang_event/Makefile diff --git a/src/mod/legacy/languages/mod_lua/Makefile.am b/src/mod/legacy/languages/mod_lua/Makefile.am new file mode 100644 index 0000000000..805b52cb69 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/Makefile.am @@ -0,0 +1,35 @@ +VERBOSE=1 +include $(top_srcdir)/build/modmake.rulesam + +MODNAME=mod_lua + +LIBLUA_A=lua/liblua.a + +AM_CFLAGS += $(CFLAGS) -D_GNU_SOURCE +mod_LTLIBRARIES = mod_lua.la +mod_lua_la_SOURCES = mod_lua.cpp freeswitch_lua.cpp mod_lua_wrap.cpp +mod_lua_la_CXXFLAGS = -Ilua $(AM_CPPFLAGS) +mod_lua_la_LIBADD = $(switch_builddir)/libfreeswitch.la +mod_lua_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm $(AM_LDFLAGS) $(LIBLUA_A) $(SOLINK) + +BUILT_SOURCES = $(LIBLUA_A) +$(mod_lua_la_SOURCES) : $(BUILT_SOURCES) + +$(LIBLUA_A): + cd lua && $(MAKE) CC="$(CC)" AR="$(AR) rcu" CFLAGS="$(AM_CFLAGS) -DLUA_USE_LINUX -w" liblua.a + +reswig: swigclean lua_wrap + +luaclean: + cd lua && $(MAKE) clean + +allclean: clean luaclean + +swigclean: clean + rm -f mod_lua_wrap.* + +lua_wrap: mod_lua_extra.c + swig -lua -c++ -I../../../../src/include -oh mod_lua_wrap.h -o mod_lua_wrap.cpp freeswitch.i + echo "#include \"mod_lua_extra.c\"" >> mod_lua_wrap.cpp + patch -s -p0 -i hack.diff + diff --git a/src/mod/legacy/languages/mod_lua/Makefile.in b/src/mod/legacy/languages/mod_lua/Makefile.in new file mode 100644 index 0000000000..75788cdee7 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/Makefile.in @@ -0,0 +1,755 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/build/modmake.rulesam +subdir = src/mod/legacy/languages/mod_lua +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/build/config/ax_compiler_vendor.m4 \ + $(top_srcdir)/build/config/ax_cflags_warn_all_ansi.m4 \ + $(top_srcdir)/build/config/ax_cc_maxopt.m4 \ + $(top_srcdir)/build/config/ax_check_compiler_flags.m4 \ + $(top_srcdir)/build/config/ac_gcc_archflag.m4 \ + $(top_srcdir)/build/config/ac_gcc_x86_cpuid.m4 \ + $(top_srcdir)/build/config/ax_lib_mysql.m4 \ + $(top_srcdir)/build/config/ax_check_java.m4 \ + $(top_srcdir)/build/config/uuid.m4 \ + $(top_srcdir)/build/config/erlang.m4 \ + $(top_srcdir)/build/config/odbc.m4 \ + $(top_srcdir)/build/config/sched_setaffinity.m4 \ + $(top_srcdir)/libs/apr/build/apr_common.m4 \ + $(top_srcdir)/libs/sofia-sip/m4/sac-pkg-config.m4 \ + $(top_srcdir)/libs/sofia-sip/m4/sac-openssl.m4 \ + $(top_srcdir)/libs/iksemel/build/libgnutls.m4 \ + $(top_srcdir)/build/config/libcurl.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/include/switch_private.h \ + $(top_builddir)/libs/xmlrpc-c/xmlrpc_amconfig.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(moddir)" +LTLIBRARIES = $(mod_LTLIBRARIES) +mod_lua_la_DEPENDENCIES = $(switch_builddir)/libfreeswitch.la +am_mod_lua_la_OBJECTS = mod_lua_la-mod_lua.lo \ + mod_lua_la-freeswitch_lua.lo mod_lua_la-mod_lua_wrap.lo +mod_lua_la_OBJECTS = $(am_mod_lua_la_OBJECTS) +mod_lua_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(mod_lua_la_CXXFLAGS) \ + $(CXXFLAGS) $(mod_lua_la_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src/include -I$(top_builddir)/libs/xmlrpc-c +depcomp = $(SHELL) $(top_srcdir)/build/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(mod_lua_la_SOURCES) +DIST_SOURCES = $(mod_lua_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_MAKEFLAGS = `test -n "$(VERBOSE)" || echo -s` +AR = @AR@ +ATTR_UNUSED = @ATTR_UNUSED@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BZIP = @BZIP@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONF_DISABLED_MODULES = @CONF_DISABLED_MODULES@ +CONF_MODULES = @CONF_MODULES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURL = @CURL@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DIRECTORY_SEPARATOR = @DIRECTORY_SEPARATOR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_LIB_EXTEN = @DYNAMIC_LIB_EXTEN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ERLANG = @ERLANG@ +ERLANG_CFLAGS = @ERLANG_CFLAGS@ +ERLANG_LDFLAGS = @ERLANG_LDFLAGS@ +ESL_LDFLAGS = @ESL_LDFLAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETG729 = @GETG729@ +GETLIB = @GETLIB@ +GETSOUNDS = @GETSOUNDS@ +GREP = @GREP@ +HAVE_LIBWWW_SSL_DEFINE = @HAVE_LIBWWW_SSL_DEFINE@ +HAVE_SYS_FILIO_H_DEFINE = @HAVE_SYS_FILIO_H_DEFINE@ +HAVE_SYS_IOCTL_H_DEFINE = @HAVE_SYS_IOCTL_H_DEFINE@ +HAVE_SYS_SELECT_H_DEFINE = @HAVE_SYS_SELECT_H_DEFINE@ +HAVE_WCHAR_H_DEFINE = @HAVE_WCHAR_H_DEFINE@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JACK_CFLAGS = @JACK_CFLAGS@ +JACK_LIBS = @JACK_LIBS@ +JAVA_FLAGS = @JAVA_FLAGS@ +JAVA_HOME = @JAVA_HOME@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBCURL_DEPS = @LIBCURL_DEPS@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_CONFIG = @LIBGNUTLS_CONFIG@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBOBJS = @LIBOBJS@ +# Dirty trick to override the link output +LIBS = @LIBS@ > $(MODNAME).log || error="yes";if test -n "$(VERBOSE)" \ + -o "$$error" = "yes";then cat $(MODNAME).log;fi;if test \ + "$$error" = "yes";then exit 1;fi +#we should set all these vars from configure, no reason to have these in each Makefile.am +LIBTOOL = echo "`link=\`echo $@|grep .la;echo $@|grep .so;echo $@|grep .dll\`;if test -n "$$link"; then echo Creating $@;fi`";`if test -z "$(VERBOSE)" ; \ +then echo $(SHELL) $(switch_builddir)/quiet_libtool ;else echo $(SHELL) $(switch_builddir)/libtool; fi` + +LIBTOOL_LIB_EXTEN = @LIBTOOL_LIB_EXTEN@ +LIBUUID_CFLAGS = @LIBUUID_CFLAGS@ +LIBUUID_LIBS = @LIBUUID_LIBS@ +LIB_JAVA = @LIB_JAVA@ +LIB_SUBDIR = @LIB_SUBDIR@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +ODBC_INC_DIR = @ODBC_INC_DIR@ +ODBC_INC_FLAGS = @ODBC_INC_FLAGS@ +ODBC_LIB_DIR = @ODBC_LIB_DIR@ +ODBC_LIB_FLAGS = @ODBC_LIB_FLAGS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OUR_CLEAN_MODS = @OUR_CLEAN_MODS@ +OUR_DISABLED_CLEAN_MODS = @OUR_DISABLED_CLEAN_MODS@ +OUR_DISABLED_INSTALL_MODS = @OUR_DISABLED_INSTALL_MODS@ +OUR_DISABLED_MODS = @OUR_DISABLED_MODS@ +OUR_DISABLED_UNINSTALL_MODS = @OUR_DISABLED_UNINSTALL_MODS@ +OUR_INSTALL_MODS = @OUR_INSTALL_MODS@ +OUR_MODS = @OUR_MODS@ +OUR_UNINSTALL_MODS = @OUR_UNINSTALL_MODS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PA_LIBS = @PA_LIBS@ +PG_CONFIG = @PG_CONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +PLATFORM_CORE_LDFLAGS = @PLATFORM_CORE_LDFLAGS@ +PLATFORM_CORE_LIBS = @PLATFORM_CORE_LIBS@ +PRTDIAG = @PRTDIAG@ +PYTHON = @PYTHON@ +PYTHON_CFLAGS = @PYTHON_CFLAGS@ +PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ +PYTHON_SITE_DIR = @PYTHON_SITE_DIR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOLINK = @SOLINK@ +SPANDSP_LA_JBIG = @SPANDSP_LA_JBIG@ +SPANDSP_LA_LZMA = @SPANDSP_LA_LZMA@ +STRIP = @STRIP@ +SWITCH_AM_CFLAGS = @SWITCH_AM_CFLAGS@ +SWITCH_AM_CXXFLAGS = @SWITCH_AM_CXXFLAGS@ +SWITCH_AM_LDFLAGS = @SWITCH_AM_LDFLAGS@ +SWITCH_ANSI_CFLAGS = @SWITCH_ANSI_CFLAGS@ +SWITCH_VERSION_MAJOR = @SWITCH_VERSION_MAJOR@ +SWITCH_VERSION_MICRO = @SWITCH_VERSION_MICRO@ +SWITCH_VERSION_MINOR = @SWITCH_VERSION_MINOR@ +SWITCH_VERSION_REVISION = @SWITCH_VERSION_REVISION@ +SWITCH_VERSION_REVISION_HUMAN = @SWITCH_VERSION_REVISION_HUMAN@ +TAR = @TAR@ +TINFO_LIBS = @TINFO_LIBS@ +TOUCH_TARGET = @TOUCH_TARGET@ +VA_LIST_IS_ARRAY_DEFINE = @VA_LIST_IS_ARRAY_DEFINE@ +VERSION = @VERSION@ +WGET = @WGET@ +XZ = @XZ@ +ZCAT = @ZCAT@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +certsdir = @certsdir@ +confdir = @confdir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbdir = @dbdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +grammardir = @grammardir@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htdocsdir = @htdocsdir@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +int64_t_fmt = @int64_t_fmt@ +int64_value = @int64_value@ +int_value = @int_value@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logfiledir = @logfiledir@ +long_value = @long_value@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +modulesdir = @modulesdir@ +oldincludedir = @oldincludedir@ +openssl_CFLAGS = @openssl_CFLAGS@ +openssl_LIBS = @openssl_LIBS@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +recordingsdir = @recordingsdir@ +runtimedir = @runtimedir@ +sbindir = @sbindir@ +scriptdir = @scriptdir@ +sharedstatedir = @sharedstatedir@ +short_value = @short_value@ +size_t_fmt = @size_t_fmt@ +size_t_value = @size_t_value@ +soundsdir = @soundsdir@ +srcdir = @srcdir@ +ssize_t_fmt = @ssize_t_fmt@ +ssize_t_value = @ssize_t_value@ +storagedir = @storagedir@ +subdirs = @subdirs@ +switch_builddir = @switch_builddir@ +switch_srcdir = @switch_srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uint64_t_fmt = @uint64_t_fmt@ +voidp_size = @voidp_size@ +VERBOSE = 1 +AM_CFLAGS = $(SWITCH_AM_CFLAGS) $(SWITCH_ANSI_CFLAGS) $(CFLAGS) \ + -D_GNU_SOURCE +AM_CPPFLAGS = $(SWITCH_AM_CXXFLAGS) +AM_LDFLAGS = $(SWITCH_AM_LDFLAGS) +moddir = @modulesdir@ +MODNAME = mod_lua +LIBLUA_A = lua/liblua.a +mod_LTLIBRARIES = mod_lua.la +mod_lua_la_SOURCES = mod_lua.cpp freeswitch_lua.cpp mod_lua_wrap.cpp +mod_lua_la_CXXFLAGS = -Ilua $(AM_CPPFLAGS) +mod_lua_la_LIBADD = $(switch_builddir)/libfreeswitch.la +mod_lua_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm $(AM_LDFLAGS) $(LIBLUA_A) $(SOLINK) +BUILT_SOURCES = $(LIBLUA_A) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .cpp .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/modmake.rulesam $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/mod/legacy/languages/mod_lua/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/mod/legacy/languages/mod_lua/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; +$(top_srcdir)/build/modmake.rulesam: + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-modLTLIBRARIES: $(mod_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(mod_LTLIBRARIES)'; test -n "$(moddir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(moddir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(moddir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(moddir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(moddir)"; \ + } + +uninstall-modLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(mod_LTLIBRARIES)'; test -n "$(moddir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(moddir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(moddir)/$$f"; \ + done + +clean-modLTLIBRARIES: + -test -z "$(mod_LTLIBRARIES)" || rm -f $(mod_LTLIBRARIES) + @list='$(mod_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +mod_lua.la: $(mod_lua_la_OBJECTS) $(mod_lua_la_DEPENDENCIES) $(EXTRA_mod_lua_la_DEPENDENCIES) + $(mod_lua_la_LINK) -rpath $(moddir) $(mod_lua_la_OBJECTS) $(mod_lua_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_lua_la-freeswitch_lua.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_lua_la-mod_lua.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_lua_la-mod_lua_wrap.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mod_lua_la-mod_lua.lo: mod_lua.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_lua_la_CXXFLAGS) $(CXXFLAGS) -MT mod_lua_la-mod_lua.lo -MD -MP -MF $(DEPDIR)/mod_lua_la-mod_lua.Tpo -c -o mod_lua_la-mod_lua.lo `test -f 'mod_lua.cpp' || echo '$(srcdir)/'`mod_lua.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/mod_lua_la-mod_lua.Tpo $(DEPDIR)/mod_lua_la-mod_lua.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='mod_lua.cpp' object='mod_lua_la-mod_lua.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_lua_la_CXXFLAGS) $(CXXFLAGS) -c -o mod_lua_la-mod_lua.lo `test -f 'mod_lua.cpp' || echo '$(srcdir)/'`mod_lua.cpp + +mod_lua_la-freeswitch_lua.lo: freeswitch_lua.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_lua_la_CXXFLAGS) $(CXXFLAGS) -MT mod_lua_la-freeswitch_lua.lo -MD -MP -MF $(DEPDIR)/mod_lua_la-freeswitch_lua.Tpo -c -o mod_lua_la-freeswitch_lua.lo `test -f 'freeswitch_lua.cpp' || echo '$(srcdir)/'`freeswitch_lua.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/mod_lua_la-freeswitch_lua.Tpo $(DEPDIR)/mod_lua_la-freeswitch_lua.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='freeswitch_lua.cpp' object='mod_lua_la-freeswitch_lua.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_lua_la_CXXFLAGS) $(CXXFLAGS) -c -o mod_lua_la-freeswitch_lua.lo `test -f 'freeswitch_lua.cpp' || echo '$(srcdir)/'`freeswitch_lua.cpp + +mod_lua_la-mod_lua_wrap.lo: mod_lua_wrap.cpp +@am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_lua_la_CXXFLAGS) $(CXXFLAGS) -MT mod_lua_la-mod_lua_wrap.lo -MD -MP -MF $(DEPDIR)/mod_lua_la-mod_lua_wrap.Tpo -c -o mod_lua_la-mod_lua_wrap.lo `test -f 'mod_lua_wrap.cpp' || echo '$(srcdir)/'`mod_lua_wrap.cpp +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/mod_lua_la-mod_lua_wrap.Tpo $(DEPDIR)/mod_lua_la-mod_lua_wrap.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='mod_lua_wrap.cpp' object='mod_lua_la-mod_lua_wrap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mod_lua_la_CXXFLAGS) $(CXXFLAGS) -c -o mod_lua_la-mod_lua_wrap.lo `test -f 'mod_lua_wrap.cpp' || echo '$(srcdir)/'`mod_lua_wrap.cpp + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(moddir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-modLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-modLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-modLTLIBRARIES + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-modLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-modLTLIBRARIES install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-modLTLIBRARIES + + +all-modules: all +depend-modules: depend +clean-modules: clean +install-modules: install +uninstall-modules: uninstall +distclean-modules: distclean +extraclean-modules: extraclean +$(mod_lua_la_SOURCES) : $(BUILT_SOURCES) + +$(LIBLUA_A): + cd lua && $(MAKE) CC="$(CC)" AR="$(AR) rcu" CFLAGS="$(AM_CFLAGS) -DLUA_USE_LINUX -w" liblua.a + +reswig: swigclean lua_wrap + +luaclean: + cd lua && $(MAKE) clean + +allclean: clean luaclean + +swigclean: clean + rm -f mod_lua_wrap.* + +lua_wrap: mod_lua_extra.c + swig -lua -c++ -I../../../../src/include -oh mod_lua_wrap.h -o mod_lua_wrap.cpp freeswitch.i + echo "#include \"mod_lua_extra.c\"" >> mod_lua_wrap.cpp + patch -s -p0 -i hack.diff + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/mod/legacy/languages/mod_lua/freeswitch.i b/src/mod/legacy/languages/mod_lua/freeswitch.i new file mode 100644 index 0000000000..6fca226001 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/freeswitch.i @@ -0,0 +1,100 @@ +%module freeswitch +%include ../../../../swig_common.i +//%include "cstring.i" + +/** + * tell swig to treat these variables as mutable so they + * can be used to return values. + * See http://www.swig.org/Doc1.3/Library.html + */ +//%cstring_bounded_mutable(char *dtmf_buf, 128); +//%cstring_bounded_mutable(char *terminator, 8); + + +/** insert the following includes into generated code so it compiles */ +%{ +#include "switch.h" +#include "switch_cpp.h" +#include "freeswitch_lua.h" +%} + + +/* Lua function typemap */ +%typemap(in, checkfn = "lua_isfunction") SWIGLUA_FN { + $1.L = L; + $1.idx = $input; +} + +%typemap(default) SWIGLUA_FN { + SWIGLUA_FN default_swiglua_fn = { 0 }; + $1 = default_swiglua_fn; +} + + +%ignore SwitchToMempool; +%newobject EventConsumer::pop; +%newobject Session; +%newobject CoreSession; +%newobject Event; +%newobject Stream; +%newobject Dbh; + +/** + * tell swig to grok everything defined in these header files and + * build all sorts of c wrappers and lua shadows of the c wrappers. + */ +%include switch_swigable_cpp.h + + +namespace LUA { +class Session : public CoreSession { + private: + virtual void do_hangup_hook(); + lua_State *getLUA(); + lua_State *L; + int hh; + int mark; + public: + Session(); + Session(char *uuid, CoreSession *a_leg = NULL); + Session(switch_core_session_t *session); + ~Session(); + virtual void destroy(const char *err = NULL); + + virtual bool begin_allow_threads(); + virtual bool end_allow_threads(); + virtual void check_hangup_hook(); + + virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype); + void unsetInputCallback(void); + void setInputCallback(char *cbfunc, char *funcargs = NULL); + void setHangupHook(char *func, char *arg = NULL); + bool ready(); + int originate(CoreSession *a_leg_session, char *dest, int timeout); + + char *cb_function; + char *cb_arg; + char *hangup_func_str; + char *hangup_func_arg; + void setLUA(lua_State *state); + +}; + +class Dbh { + private: + switch_cache_db_handle_t *dbh; + bool m_connected; + static int query_callback(void *pArg, int argc, char **argv, char **cargv); + public: + Dbh(char *dsn, char *user = NULL, char *pass = NULL); + ~Dbh(); + bool release(); + bool connected(); + bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); + bool query(char *sql, SWIGLUA_FN lua_fun); + int affected_rows(); + int load_extension(const char *extension); +}; + +} + diff --git a/src/mod/legacy/languages/mod_lua/freeswitch_lua.cpp b/src/mod/legacy/languages/mod_lua/freeswitch_lua.cpp new file mode 100644 index 0000000000..34edfaea93 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/freeswitch_lua.cpp @@ -0,0 +1,457 @@ + +#include +#include "freeswitch_lua.h" +using namespace LUA; + +extern "C" { + int docall(lua_State * L, int narg, int nresults, int perror); +}; + +Session::Session():CoreSession() +{ + cb_function = cb_arg = hangup_func_str = hangup_func_arg = NULL; + hh = mark = 0; +} + +Session::Session(char *nuuid, CoreSession *a_leg):CoreSession(nuuid, a_leg) +{ + cb_function = cb_arg = hangup_func_str = hangup_func_arg = NULL; + hh = mark = 0; +} + +Session::Session(switch_core_session_t *new_session):CoreSession(new_session) +{ + cb_function = cb_arg = hangup_func_str = hangup_func_arg = NULL; + hh = mark = 0; +} +static switch_status_t lua_hanguphook(switch_core_session_t *session_hungup); + + +void Session::destroy(const char *err) +{ + + if (!allocated) { + return; + } + + if (session) { + if (!channel) { + channel = switch_core_session_get_channel(session); + } + switch_channel_set_private(channel, "CoreSession", NULL); + switch_core_event_hook_remove_state_change(session, lua_hanguphook); + } + + switch_safe_free(hangup_func_str); + switch_safe_free(hangup_func_arg); + switch_safe_free(cb_function); + switch_safe_free(cb_arg); + + CoreSession::destroy(); + + + if (!zstr(err)) { + lua_pushstring(L, err); + lua_error(L); + } + +} + + +Session::~Session() +{ + destroy(); +} + +bool Session::begin_allow_threads() +{ + do_hangup_hook(); + return true; +} + +bool Session::end_allow_threads() +{ + do_hangup_hook(); + return true; +} + +void Session::setLUA(lua_State * state) +{ + L = state; + + if (session && allocated && uuid) { + lua_setglobal(L, uuid); + lua_getfield(L, LUA_GLOBALSINDEX, uuid); + } + +} + +int Session::originate(CoreSession *a_leg_session, char *dest, int timeout) +{ + int x = CoreSession::originate(a_leg_session, dest, timeout); + + if (x) { + setLUA(L); + } + + return x; +} + +lua_State *Session::getLUA() +{ + if (!L) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh!\n"); + } + return L; +} + + +bool Session::ready() +{ + bool r; + + if (!session) { + return false; + } + sanity_check(false); + r = switch_channel_ready(channel) != 0; + do_hangup_hook(); + + return r; +} + +void Session::check_hangup_hook() +{ + if (hangup_func_str && (hook_state == CS_HANGUP || hook_state == CS_ROUTING)) { + hh++; + } +} + +void Session::do_hangup_hook() +{ + if (hh && !mark) { + int arg_count = 2; + mark++; + + if (!getLUA()) { + return; + } + + lua_getfield(L, LUA_GLOBALSINDEX, (char *) hangup_func_str); + lua_getfield(L, LUA_GLOBALSINDEX, uuid); + + lua_pushstring(L, hook_state == CS_HANGUP ? "hangup" : "transfer"); + + if (hangup_func_arg) { + lua_getfield(L, LUA_GLOBALSINDEX, (char *) hangup_func_arg); + arg_count++; + } + + docall(L, arg_count, 1, 1); + + const char *err = lua_tostring(L, -1); + + switch_channel_set_variable(channel, "lua_hangup_hook_return_val", err); + + if (!zstr(err)) { + + if (!strcasecmp(err, "exit") || !strcasecmp(err, "die")) { + lua_error(L); + } else { + lua_pop(L, 1); + } + } else { + lua_pop(L, 1); + } + + + if (channel) { + switch_channel_set_private(channel, "CoreSession", NULL); + } + + if (session) { + switch_core_event_hook_remove_state_change(session, lua_hanguphook); + } + switch_safe_free(hangup_func_str); + + } +} + +static switch_status_t lua_hanguphook(switch_core_session_t *session_hungup) +{ + switch_channel_t *channel = switch_core_session_get_channel(session_hungup); + Session *coresession = NULL; + switch_channel_state_t state = switch_channel_get_state(channel); + + if (session_hungup) { + + channel = switch_core_session_get_channel(session_hungup); + + if (channel) { + void *vs = switch_channel_get_private(channel, "CoreSession"); + if (vs) { + coresession = (Session *) vs; + } + } + + if (!(coresession && coresession->hook_state)) { + return SWITCH_STATUS_FALSE; + } + + if (coresession && coresession->allocated && (state == CS_HANGUP || state == CS_ROUTING) && coresession->hook_state != state) { + coresession->hook_state = state; + coresession->check_hangup_hook(); + switch_core_event_hook_remove_state_change(session_hungup, lua_hanguphook); + } + } + + return SWITCH_STATUS_SUCCESS; +} + + +void Session::setHangupHook(char *func, char *arg) +{ + + sanity_check_noreturn; + + switch_safe_free(hangup_func_str); + switch_safe_free(hangup_func_arg); + + if (func) { + hangup_func_str = strdup(func); + if (!zstr(arg)) { + hangup_func_arg = strdup(arg); + } + switch_channel_set_private(channel, "CoreSession", this); + hook_state = switch_channel_get_state(channel); + switch_core_event_hook_add_state_change(session, lua_hanguphook); + } +} + +void Session::unsetInputCallback(void) +{ + sanity_check_noreturn; + switch_safe_free(cb_function); + switch_safe_free(cb_arg); + args.input_callback = NULL; + ap = NULL; +} + +void Session::setInputCallback(char *cbfunc, char *funcargs) +{ + + sanity_check_noreturn; + + switch_safe_free(cb_function); + if (cbfunc) { + cb_function = strdup(cbfunc); + } + + switch_safe_free(cb_arg); + if (funcargs) { + cb_arg = strdup(funcargs); + } + + args.buf = this; + switch_channel_set_private(channel, "CoreSession", this); + + args.input_callback = dtmf_callback; + ap = &args; +} + +switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype) +{ + const char *ret; + + if (!getLUA()) { + return SWITCH_STATUS_FALSE;; + } + + switch (itype) { + case SWITCH_INPUT_TYPE_DTMF: + { + switch_dtmf_t *dtmf = (switch_dtmf_t *) input; + char str[3] = ""; + int arg_count = 3; + + lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_function); + lua_getfield(L, LUA_GLOBALSINDEX, uuid); + + lua_pushstring(L, "dtmf"); + + lua_newtable(L); + lua_pushstring(L, "digit"); + str[0] = dtmf->digit; + lua_pushstring(L, str); + lua_rawset(L, -3); + + lua_pushstring(L, "duration"); + lua_pushnumber(L, dtmf->duration); + lua_rawset(L, -3); + + if (!zstr(cb_arg)) { + lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_arg); + arg_count++; + } + + docall(L, arg_count, 1, 1); + + ret = lua_tostring(L, -1); + lua_pop(L, 1); + + return process_callback_result((char *) ret); + } + break; + case SWITCH_INPUT_TYPE_EVENT: + { + switch_event_t *event = (switch_event_t *) input; + int arg_count = 3; + + + lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_function); + lua_getfield(L, LUA_GLOBALSINDEX, uuid); + lua_pushstring(L, "event"); + mod_lua_conjure_event(L, event, "__Input_Event__", 1); + lua_getfield(L, LUA_GLOBALSINDEX, "__Input_Event__"); + + if (!zstr(cb_arg)) { + lua_getfield(L, LUA_GLOBALSINDEX, (char *) cb_arg); + arg_count++; + } + + docall(L, arg_count, 1, 1); + ret = lua_tostring(L, -1); + lua_pop(L, 1); + + return process_callback_result((char *) ret); + } + break; + } + + return SWITCH_STATUS_SUCCESS; +} + + +Dbh::Dbh(char *dsn, char *user, char *pass) +{ + dbh = NULL; + char *tmp = NULL; + + if (!zstr(user) || !zstr(pass)) { + tmp = switch_mprintf("%s%s%s%s%s", dsn, + zstr(user) ? "" : ":", + zstr(user) ? "" : user, + zstr(pass) ? "" : ":", + zstr(pass) ? "" : pass + ); + + dsn = tmp; + } + + if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "DBH handle %p Connected.\n", (void *) dbh); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Connection failed. DBH NOT Connected.\n"); + } + + switch_safe_free(tmp); + +} + +Dbh::~Dbh() +{ + if (dbh) release(); +} + +bool Dbh::release() +{ + if (dbh) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "DBH handle %p released.\n", (void *) dbh); + switch_cache_db_release_db_handle(&dbh); + return true; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DBH NOT Connected.\n"); + return false; +} + +bool Dbh::connected() +{ + return dbh ? true : false; +} + +bool Dbh::test_reactive(char *test_sql, char *drop_sql, char *reactive_sql) +{ + if (dbh) { + if (switch_cache_db_test_reactive(dbh, test_sql, drop_sql, reactive_sql) == SWITCH_TRUE) { + return true; + } + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DBH NOT Connected.\n"); + return false; +} + +int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv) +{ + SWIGLUA_FN *lua_fun = (SWIGLUA_FN *)pArg; + int ret = 0; + + lua_pushvalue(lua_fun->L, lua_fun->idx); /* get the lua callback function onto the stack */ + + lua_newtable(lua_fun->L); /* push a row (table) */ + + for (int i = 0; i < argc; i++) { + lua_pushstring(lua_fun->L, switch_str_nil(cargv[i])); + lua_pushstring(lua_fun->L, switch_str_nil(argv[i])); + lua_settable(lua_fun->L, -3); + } + + docall(lua_fun->L, 1, 1, 1); + ret = lua_tonumber(lua_fun->L, -1); + lua_pop(lua_fun->L, 1); + + if (ret != 0) { + return 1; + } + + return 0; /* 0 to continue with next row */ +} + +bool Dbh::query(char *sql, SWIGLUA_FN lua_fun) +{ + if (dbh) { + if (lua_fun.L) { + if (switch_cache_db_execute_sql_callback(dbh, sql, query_callback, &lua_fun, NULL) == SWITCH_STATUS_SUCCESS) { + return true; + } + } else { /* if no lua_fun arg is passed from Lua, an empty initialized struct will be sent - see freeswitch.i */ + if (switch_cache_db_execute_sql(dbh, sql, NULL) == SWITCH_STATUS_SUCCESS) { + return true; + } + } + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DBH NOT Connected.\n"); + return false; +} + +int Dbh::affected_rows() +{ + if (dbh) { + return switch_cache_db_affected_rows(dbh); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DBH NOT Connected.\n"); + return 0; +} + +int Dbh::load_extension(const char *extension) +{ + if (dbh) { + return switch_cache_db_load_extension(dbh, extension); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DBH NOT Connected.\n"); + return 0; +} diff --git a/src/mod/legacy/languages/mod_lua/freeswitch_lua.h b/src/mod/legacy/languages/mod_lua/freeswitch_lua.h new file mode 100644 index 0000000000..a1a289a70b --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/freeswitch_lua.h @@ -0,0 +1,71 @@ +#ifndef FREESWITCH_LUA_H +#define FREESWITCH_LUA_H + +extern "C" { +#include "lua.h" +#include +#include +#include "mod_lua_extra.h" +} +#include + + +typedef struct{ + lua_State* L; + int idx; +}SWIGLUA_FN; + +#define SWIGLUA_FN_GET(fn) {lua_pushvalue(fn.L,fn.idx);} + + +namespace LUA { + class Session:public CoreSession { + private: + virtual void do_hangup_hook(); + lua_State *getLUA(); + lua_State *L; + int hh; + int mark; + public: + Session(); + Session(char *uuid, CoreSession * a_leg = NULL); + Session(switch_core_session_t *session); + ~Session(); + SWITCH_MOD_DECLARE(virtual void) destroy(const char *err = NULL); + + virtual bool begin_allow_threads(); + virtual bool end_allow_threads(); + virtual void check_hangup_hook(); + + virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype); + void unsetInputCallback(void); + void setInputCallback(char *cbfunc, char *funcargs = NULL); + void setHangupHook(char *func, char *arg = NULL); + bool ready(); + int originate(CoreSession * a_leg_session, char *dest, int timeout); + + char *cb_function; + char *cb_arg; + char *hangup_func_str; + char *hangup_func_arg; + void setLUA(lua_State * state); + + }; + + class Dbh { + protected: + switch_cache_db_handle_t *dbh; + bool m_connected; + static int query_callback(void *pArg, int argc, char **argv, char **cargv); + public: + Dbh(char *dsn, char *user = NULL, char *pass = NULL); + ~Dbh(); + bool release(); + bool connected(); + bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); + bool query(char *sql, SWIGLUA_FN lua_fun); + int affected_rows(); + int load_extension(const char *extension); + }; +} +#endif diff --git a/src/mod/legacy/languages/mod_lua/hack.diff b/src/mod/legacy/languages/mod_lua/hack.diff new file mode 100644 index 0000000000..fc33ddb9d6 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/hack.diff @@ -0,0 +1,38 @@ +--- mod_lua_wrap.cpp.orig 2010-09-05 16:39:26.000000000 +0200 ++++ mod_lua_wrap.cpp 2010-09-05 16:39:44.000000000 +0200 +@@ -4913,7 +4913,7 @@ + + result = (LUA::Session *)new LUA::Session(); + SWIG_arg=0; +- SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; ++ SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); + return SWIG_arg; + + fail: +@@ -4934,7 +4934,7 @@ + arg2=(CoreSession *)SWIG_MustGetPtr(L,2,SWIGTYPE_p_CoreSession,0,2,"new_Session"); + result = (LUA::Session *)new LUA::Session(arg1,arg2); + SWIG_arg=0; +- SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; ++ SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); + return SWIG_arg; + + fail: +@@ -4952,7 +4952,7 @@ + arg1 = (char*)lua_tostring(L, 1); + result = (LUA::Session *)new LUA::Session(arg1); + SWIG_arg=0; +- SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; ++ SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); + return SWIG_arg; + + fail: +@@ -4970,7 +4970,7 @@ + arg1=(switch_core_session_t *)SWIG_MustGetPtr(L,1,SWIGTYPE_p_switch_core_session_t,0,1,"new_Session"); + result = (LUA::Session *)new LUA::Session(arg1); + SWIG_arg=0; +- SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; ++ SWIG_NewPointerObj(L,result,SWIGTYPE_p_LUA__Session,1); SWIG_arg++; result->setLUA(L); + return SWIG_arg; + + fail: diff --git a/src/mod/legacy/languages/mod_lua/lua-mode.el b/src/mod/legacy/languages/mod_lua/lua-mode.el new file mode 100644 index 0000000000..bf52b4f4df --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua-mode.el @@ -0,0 +1,1338 @@ +;;; lua-mode.el --- a major-mode for editing Lua scripts + +;; Copyright (C) 1997, 2001, 2004, 2006, 2007 Free Software Foundation, Inc. + +;; Author: 2006 Juergen Hoetzel +;; 2004 various (support for Lua 5 and byte compilation) +;; 2001 Christian Vogler +;; 1997 Bret Mogilefsky starting from +;; tcl-mode by Gregor Schmid +;; with tons of assistance from +;; Paul Du Bois and +;; Aaron Smith . +;; URL: http://lua-mode.luaforge.net/ +;; Version: 20070703 +;; This file is NOT part of Emacs. +;; +;; 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., 51 Franklin Street, Fifth Floor, Boston, +;; MA 02110-1301, USA. + +(defconst lua-version "20071122" + "Lua Mode version number.") + +;; Keywords: languages, processes, tools + + +;;; Commentary: + +;; Thanks to Tobias Polzin gmx.de> for function indenting +;; patch: Indent "(" like "{" + +;; Thanks to Fabien gmail.com> for imenu patches. + +;; Special Thanks to Simon Marshall for +;; font-lock patches. + +;; Additional font-lock highlighting and indentation tweaks by +;; Adam D. Moss + +;; This file was written with emacs using Jamie Lokier's folding mode +;; That's what the funny ;;{{{ ;;}}} marks are there for + +;;{{{ INSTALLATION: + +;; To install, just drop this file into a directory on your load-path (and +;; byte-compile it). To set up Emacs to automatically edit files ending in +;; ".lua" using lua-mode add the following to your ~/.emacs file (GNU +;; Emacs) or ~/.xemacs/init.el file (XEmacs): +;; (setq auto-mode-alist (cons '("\\.lua$" . lua-mode) auto-mode-alist)) +;; (autoload 'lua-mode "lua-mode" "Lua editing mode." t) + +;;}}} +;;{{{ Usage + +;; Lua-mode supports c-mode style formatting and sending of +;; lines/regions/files to a Lua interpreter. An interpreter (see +;; variable `lua-default-application') will be started if you try to +;; send some code and none is running. You can use the process-buffer +;; (named after the application you chose) as if it were an +;; interactive shell. See the documentation for `comint.el' for +;; details. + +;;}}} +;;{{{ Key-bindings + +;; To see all the keybindings for Lua mode, look at `lua-setup-keymap' +;; or start `lua-mode' and type `\C-h m'. +;; The keybindings may seem strange, since I prefer to use them with +;; lua-prefix-key set to nil, but since those keybindings are already used +;; the default for `lua-prefix-key' is `\C-c', which is the conventional +;; prefix for major-mode commands. + +;; You can customise the keybindings either by setting `lua-prefix-key' +;; or by putting the following in your .emacs +;; (setq lua-mode-map (make-sparse-keymap)) +;; and +;; (define-key lua-mode-map ) +;; for all the functions you need. + +;;}}} + +;;; Code: +(defconst lua-using-xemacs (string-match "XEmacs" emacs-version) + "Nil unless using XEmacs).") + +;; We need that ! +(require 'comint) + +;;{{{ variables + +;; Local variables +(defgroup lua nil + "Major mode for editing lua code." + :prefix "lua-" + :group 'languages) + +(defcustom lua-default-application "lua" + "Default application to run in lua subprocess." + :type 'string + :group 'lua) + +(defcustom lua-default-command-switches (list "-i") + "Command switches for `lua-default-application'. +Should be a list of strings." + :type '(repeat string) + :group 'lua) + +(defcustom lua-always-show t + "*Non-nil means display lua-process-buffer after sending a command." + :type 'boolean + :group 'lua) + +(defcustom lua-search-url-prefix "http://www.lua.org/manual/5.1/manual.html#pdf-" + "*URL at which to search for documentation on a word" + :type 'string + :group 'lua) + +(defvar lua-process nil + "The active Lua subprocess") + +(defvar lua-process-buffer nil + "Buffer used for communication with Lua subprocess") + +(defvar lua-mode-map nil + "Keymap used with lua-mode.") + +(defvar lua-electric-flag t +"If t, electric actions (like automatic reindentation) will happen when an electric + key like `{' is pressed") +(make-variable-buffer-local 'lua-electric-flag) + +(defcustom lua-prefix-key "\C-c" + "Prefix for all lua-mode commands." + :type 'string + :group 'lua) + +(defcustom lua-prompt-regexp "[^\n]*\\(>[\t ]+\\)+$" + "Regexp which matches the Lua program's prompt." + :group 'lua + :type 'regexp + ) + +(defcustom lua-traceback-line-re + "^\\(?:[\t ]*\\|.*>[\t ]+\\)\\([^\n\t ]+\\):\\([0-9]+\\):" + "Regular expression that describes tracebacks and errors." + :group 'lua + :type 'regexp + ) + +(defcustom lua-jump-on-traceback t + "*Jump to innermost traceback location in *lua* buffer. When this +variable is non-nil and a traceback occurs when running Lua code in a +subprocess, jump immediately to the source code of the innermost +traceback location." + :group 'lua + :type 'boolean + ) + +(defvar lua-mode-hook nil + "Hooks called when Lua mode fires up.") + +(defvar lua-region-start (make-marker) + "Start of special region for Lua communication.") + +(defvar lua-region-end (make-marker) + "End of special region for Lua communication.") + +(defvar lua-indent-level 3 + "Amount by which Lua subexpressions are indented.") + +(defvar lua-mode-menu (make-sparse-keymap "Lua") + "Keymap for lua-mode's menu.") + +(defvar lua-xemacs-menu + '(["Restart With Whole File" lua-restart-with-whole-file t] + ["Kill Process" lua-kill-process t] + ["Hide Process Buffer" lua-hide-process-buffer t] + ["Show Process Buffer" lua-show-process-buffer t] + ["Beginning Of Proc" lua-beginning-of-proc t] + ["End Of Proc" lua-end-of-proc t] + ["Set Lua-Region Start" lua-set-lua-region-start t] + ["Set Lua-Region End" lua-set-lua-region-end t] + ["Send Lua-Region" lua-send-lua-region t] + ["Send Current Line" lua-send-current-line t] + ["Send Region" lua-send-region t] + ["Send Proc" lua-send-proc t] + ["Send Buffer" lua-send-buffer t] + ["Search Documentation" lua-search-documentation t]) + "XEmacs menu for Lua mode.") + +(defvar lua-font-lock-keywords + (eval-when-compile + (list + ;; + ;; Function name declarations. + '("^[ \t]*\\<\\(\\(local[ \t]+\\)?function\\)\\>[ \t]+\\(\\(\\sw:\\|\\sw\\.\\|\\sw_\\|\\sw\\)+\\)" + (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) + + ;; Handle function names in assignments + '("\\(\\(\\sw:\\|\\sw\\.\\|\\sw_\\|\\sw\\)+\\)[ \t]*=[ \t]*\\(function\\)\\>" + (1 font-lock-function-name-face nil t) (3 font-lock-keyword-face)) + + ; Highlight multi-line comment blocks; since font-lock-mode doesn't + ; claim to handle the highlighting of multi-line expressions elegantly + ; this works best with lazy-lock-mode if your Emacs supports it, e.g. + ; try (setq font-lock-support-mode 'lazy-lock-mode) in your ~/.emacs + + ;; Multi-line comment blocks. + `("\\(?:^\\|[^-]\\)\\(--\\[\\(=*\\)\\[\\(?:.\\|\n\\)*?\\]\\2\\]\\)" + (1 font-lock-comment-face t)) + + ;; + ;; Keywords. + ;; (concat "\\<" + ;; (regexp-opt '("and" "break" "do" "else" "elseif" "end" "false" + ;; "for" "function" "if" "in" "local" "nil" "not" + ;; "or" "repeat" "return" "then" "true" "until" + ;; "while") t) + ;; "\\>") + + ; Insert expanded regexp-opt here for the benefit of those who + ; don't have regexp-opt available. + + "\\<\\(and\\|break\\|do\\|e\\(lse\\(if\\)?\\|nd\\)\\|f\\(alse\\|or\\|unction\\)\\|i[fn]\\|local\\|n\\(il\\|ot\\)\\|or\\|re\\(peat\\|turn\\)\\|t\\(hen\\|rue\\)\\|until\\|while\\)\\>" + + "Default expressions to highlight in Lua mode."))) + +(defvar lua-imenu-generic-expression + '((nil "^[ \t]*\\(?:local[ \t]+\\)?function[ \t]+\\(\\(\\sw:\\|\\sw_\\|\\sw\\.\\|\\sw\\)+\\)" 1)) + "Imenu generic expression for lua-mode. See `imenu-generic-expression'.") + +(defvar lua-mode-abbrev-table nil + "Abbreviation table used in lua-mode buffers.") + +(defvar lua-sexp-alist '(("then" . "end") + ("function" . "end") + ("do" . "end"))) + +(define-abbrev-table 'lua-mode-abbrev-table + '( + ("end" "end" lua-indent-line 0) + ("else" "else" lua-indent-line 0) + ("elseif" "elseif" lua-indent-line 0) + )) + +(defconst lua-indent-whitespace " \t" + "Character set that constitutes whitespace for indentation in lua.") + +;;}}} +;;{{{ lua-make-temp-file + +(eval-and-compile + (defalias 'lua-make-temp-file + (if (fboundp 'make-temp-file) + 'make-temp-file + (lambda (prefix &optional dir-flag) ;; Simple implementation + (expand-file-name + (make-temp-name prefix) + (if (fboundp 'temp-directory) + (temp-directory) + temporary-file-directory)))))) + +;;}}} +;;{{{ replace-in-string + +(eval-and-compile + (if (not (fboundp 'replace-in-string)) ;GNU emacs doesn't have it + (defun replace-in-string (string regexp newtext &optional literal) + (replace-regexp-in-string regexp newtext string nil literal)))) + +;;}}} +;;{{{ lua-mode + +;;;###autoload +(defun lua-mode () + "Major mode for editing Lua code. +The following keys are bound: +\\{lua-mode-map} +" + (interactive) + (let ((switches nil) + s) + (kill-all-local-variables) + (setq major-mode 'lua-mode) + (setq mode-name "Lua") + (setq comint-prompt-regexp lua-prompt-regexp) + (make-local-variable 'lua-default-command-switches) + (set (make-local-variable 'indent-line-function) 'lua-indent-line) + (set (make-local-variable 'comment-start) "--") + (set (make-local-variable 'comment-start-skip) "--") + (set (make-local-variable 'font-lock-defaults) + '(lua-font-lock-keywords nil nil ((?_ . "w")))) + (set (make-local-variable 'imenu-generic-expression) + lua-imenu-generic-expression) + (setq local-abbrev-table lua-mode-abbrev-table) + (abbrev-mode 1) + (make-local-variable 'lua-default-eval) + (or lua-mode-map + (lua-setup-keymap)) + (use-local-map lua-mode-map) + (set-syntax-table (copy-syntax-table)) + (modify-syntax-entry ?+ ".") + (modify-syntax-entry ?- ". 12") + (modify-syntax-entry ?* ".") + (modify-syntax-entry ?/ ".") + (modify-syntax-entry ?^ ".") + ;; This might be better as punctuation, as for C, but this way you + ;; can treat table index as symbol. + (modify-syntax-entry ?. "_") ; e.g. `io.string' + (modify-syntax-entry ?> ".") + (modify-syntax-entry ?< ".") + (modify-syntax-entry ?= ".") + (modify-syntax-entry ?~ ".") + (modify-syntax-entry ?\n ">") + (modify-syntax-entry ?\' "\"") + (modify-syntax-entry ?\" "\"") + ;; _ needs to be part of a word, or the regular expressions will + ;; incorrectly regognize end_ to be matched by "\\"! + (modify-syntax-entry ?_ "w") + (if (and lua-using-xemacs + (featurep 'menubar) + current-menubar + (not (assoc "Lua" current-menubar))) + (progn + (set-buffer-menubar (copy-sequence current-menubar)) + (add-menu nil "Lua" lua-xemacs-menu))) + ;; Append Lua menu to popup menu for XEmacs. + (if (and lua-using-xemacs (boundp 'mode-popup-menu)) + (setq mode-popup-menu + (cons (concat mode-name " Mode Commands") lua-xemacs-menu))) + + ;; hideshow setup + (unless (assq 'lua-mode hs-special-modes-alist) + (add-to-list 'hs-special-modes-alist + `(lua-mode + ,(regexp-opt (mapcar 'car lua-sexp-alist) 'words);start + ,(regexp-opt (mapcar 'cdr lua-sexp-alist) 'words) ;end + nil lua-forward-sexp))) + (run-hooks 'lua-mode-hook))) + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.lua$" . lua-mode)) + +;;}}} +;;{{{ lua-setup-keymap + +(defun lua-setup-keymap () + "Set up keymap for Lua mode. +If the variable `lua-prefix-key' is nil, the bindings go directly +to `lua-mode-map', otherwise they are prefixed with `lua-prefix-key'." + (setq lua-mode-map (make-sparse-keymap)) + (define-key lua-mode-map [menu-bar lua-mode] + (cons "Lua" lua-mode-menu)) + (define-key lua-mode-map "}" 'lua-electric-match) + (define-key lua-mode-map "]" 'lua-electric-match) + (define-key lua-mode-map ")" 'lua-electric-match) + (let ((map (if lua-prefix-key + (make-sparse-keymap) + lua-mode-map))) + + ;; communication + (define-key map "\M-[" 'lua-beginning-of-proc) + (define-key map "\M-]" 'lua-end-of-proc) + (define-key map "\C-c" 'comment-region) + (define-key map "\C-l" 'lua-send-buffer) + (define-key map "\C-f" 'lua-search-documentation) + (if lua-prefix-key + (define-key lua-mode-map lua-prefix-key map)) + )) + +;;}}} +;;{{{ lua-electric-match + +(defun lua-electric-match (arg) + "Insert character and adjust indentation." + (interactive "P") + (insert-char last-command-char (prefix-numeric-value arg)) + (if lua-electric-flag + (lua-indent-line)) + (blink-matching-open)) + +;;}}} + +;;{{{ private functions +(defun lua-syntax-status () + "Returns the syntactic status of the character after the point." + (parse-partial-sexp (save-excursion (beginning-of-line) (point)) + (point))) + + +(defun lua-string-p () + "Returns true if the point is in a string." + (elt (lua-syntax-status) 3)) + +(defun lua-comment-p () + "Returns true if the point is in a comment." + (elt (lua-syntax-status) 4)) + +(defun lua-comment-or-string-p () + "Returns true if the point is in a comment or string." + (let ((parse-result (lua-syntax-status))) + (or (elt parse-result 3) (elt parse-result 4)))) + +;;}}} +;;{{{ lua-indent-line + +(defun lua-indent-line () + "Indent current line for Lua mode. +Return the amount the indentation changed by." + (let ((indent (max 0 (- (lua-calculate-indentation nil) + (lua-calculate-indentation-left-shift)))) + beg shift-amt + (case-fold-search nil) + (pos (- (point-max) (point)))) + (beginning-of-line) + (setq beg (point)) + (skip-chars-forward lua-indent-whitespace) + (setq shift-amt (- indent (current-column))) + (when (not (zerop shift-amt)) + (delete-region beg (point)) + (indent-to indent)) + ;; If initial point was within line's indentation, + ;; position after the indentation. Else stay at same point in text. + (if (> (- (point-max) pos) (point)) + (goto-char (- (point-max) pos))) + shift-amt + indent)) + +;;}}} +;;{{{ lua-find-regexp + +(defun lua-find-regexp (direction regexp &optional limit ignore-p) + "Searches for a regular expression in the direction specified. +Direction is one of 'forward and 'backward. +By default, matches in comments and strings are ignored, but what to ignore is +configurable by specifying ignore-p. If the regexp is found, returns point +position, nil otherwise. +ignore-p returns true if the match at the current point position should be +ignored, nil otherwise." + (let ((ignore-func (or ignore-p 'lua-comment-or-string-p)) + (search-func (if (eq direction 'forward) + 're-search-forward 're-search-backward)) + (case-fold-search nil)) + (catch 'found + (while (funcall search-func regexp limit t) + (if (not (funcall ignore-func)) + (throw 'found (point))))))) + +;;}}} +;;{{{ lua-backwards-to-block-begin-or-end + +(defun lua-backwards-to-block-begin-or-end () + "Move backwards to nearest block begin or end. Returns nil if not successful." + (interactive) + (lua-find-regexp 'backward lua-block-regexp)) + +;;}}} +;;{{{ var. constants + +(defconst lua-block-regexp + (eval-when-compile + ;; This is the code we used to generate the regexp: + (concat + "\\(\\<" + (regexp-opt '("do" "function" "repeat" "then" + "else" "elseif" "end" "until") t) + "\\>\\)\\|" + (regexp-opt '("{" "(" "[" "]" ")" "}") t)) + + )) + +(defconst lua-block-token-alist + ;; The absence of "else" is deliberate. This construct in a way both + ;; opens and closes a block. As a result, it is difficult to handle + ;; cleanly. It is also ambiguous - if we are looking for the match + ;; of "else", should we look backward for "then/elseif" or forward + ;; for "end"? + ;; Maybe later we will find a way to handle it. + '(("do" "\\" open) + ("function" "\\" open) + ("repeat" "\\" open) + ("then" "\\<\\(e\\(lseif\\|nd\\)\\)\\>" open) + ("{" "}" open) + ("[" "]" open) + ("(" ")" open) + ("elseif" "\\" close) + ("end" "\\<\\(do\\|function\\|then\\)\\>" close) + ("until" "\\" close) + ("}" "{" close) + ("]" "\\[" close) + (")" "(" close))) + + +(defconst lua-indentation-modifier-regexp + ;; The absence of else is deliberate, since it does not modify the + ;; indentation level per se. It only may cause the line, in which the + ;; else is, to be shifted to the left. + ;; This is the code we used to generate the regexp: + (concat + "\\(\\<" + ; n.b. "local function" is a bit of a hack, allowing only a single space + (regexp-opt '("do" "local function" "function" "repeat" "then") t) + "\\>\\|" + (regexp-opt '("{" "(" "[")) + "\\)\\|\\(\\<" + (regexp-opt '("elseif" "end" "until") t) + "\\>\\|" + (regexp-opt '("]" ")" "}")) + "\\)") + + ) + +;;}}} +;;{{{ lua-find-matching-token-word + +(defun lua-find-matching-token-word (token search-start) + (let* ((token-info (assoc token lua-block-token-alist)) + (match (car (cdr token-info))) + (match-type (car (cdr (cdr token-info)))) + (search-direction (if (eq match-type 'open) 'forward 'backward))) + ;; if we are searching forward from the token at the current point + ;; (i.e. for a closing token), need to step one character forward + ;; first, or the regexp will match the opening token. + (if (eq match-type 'open) (forward-char 1)) + (if search-start (goto-char search-start)) + (catch 'found + (while (lua-find-regexp search-direction lua-indentation-modifier-regexp) + ;; have we found a valid matching token? + (let ((found-token (match-string 0)) + (found-pos (match-beginning 0))) + (if (string-match match found-token) + (throw 'found found-pos)) + ;; no - then there is a nested block. If we were looking for + ;; a block begin token, found-token must be a block end + ;; token; likewise, if we were looking for a block end token, + ;; found-token must be a block begin token, otherwise there + ;; is a grammatical error in the code. + (if (not (and + (eq (car (cdr (cdr (assoc found-token lua-block-token-alist)))) + match-type) + (lua-find-matching-token-word found-token nil))) + (throw 'found nil))))))) + +;;}}} +;;{{{ lua-goto-matching-block-token + +(defun lua-goto-matching-block-token (&optional search-start parse-start) + "Find block begion/end token matching the one at the point. +This function moves the point to the token that matches the one +at the current point. Returns the point position of the first character of +the matching token if successful, nil otherwise." + (if parse-start (goto-char parse-start)) + (let ((case-fold-search nil)) + (if (looking-at lua-indentation-modifier-regexp) + (let ((position (lua-find-matching-token-word (match-string 0) + search-start))) + (and position + (goto-char position)))))) + + +;; The following may be useful to speed up the search in the future. +; (let ((token-type (char-syntax (string-to-char token-to-match))) +; matching-pos) +; (cond ((eq token-type ?\() +; (setq matching-pos (scan-sexps (point) 1 (current-buffer) t)) +; (when matching-pos (goto-char matching-pos))) + +; ((eq token-type ?\)) +; ;; need to move one char forward, because scan-sexps +; ;; expects the point to be one past the closing parenthesis +; (forward-char 1) +; (setq matching-pos (scan-sexps (point) -1 (current-buffer) t)) +; (when matching-pos (goto-char matching-pos))) + +; (t +; (lua-goto-matching-token-word token-to-match search-start))))))) + + +;;}}} +;;{{{ lua-goto-matching-block + +(defun lua-goto-matching-block (&optional noreport) + "Go to the keyword balancing the one under the point. +If the point is on a keyword/brace that starts a block, go to the +matching keyword that ends the block, and vice versa." + (interactive) + ;; search backward to the beginning of the keyword if necessary + (if (eq (char-syntax (following-char)) ?w) + (re-search-backward "\\<" nil t)) + (let ((position (lua-goto-matching-block-token))) + (if (and (not position) + (not noreport)) + (error "Not on a block control keyword or brace.") + position))) + +;;}}} +;;{{{ lua-goto-nonblank-previous-line + +(defun lua-goto-nonblank-previous-line () + "Puts the point at the first previous line that is not blank. +Returns the point, or nil if it reached the beginning of the buffer" + (catch 'found + (beginning-of-line) + (while t + (if (bobp) (throw 'found nil)) + (forward-char -1) + (beginning-of-line) + (if (not (looking-at "\\s *\\(--.*\\)?$")) (throw 'found (point)))))) + +;;}}} +;;{{{ lua-goto-nonblank-next-line + +(defun lua-goto-nonblank-next-line () + "Puts the point at the first next line that is not blank. +Returns the point, or nil if it reached the end of the buffer" + (catch 'found + (end-of-line) + (while t + (forward-line) + (if (eobp) (throw 'found nil)) + (beginning-of-line) + (if (not (looking-at "\\s *\\(--.*\\)?$")) (throw 'found (point)))))) + +(eval-when-compile + (defconst lua-operator-class + "-+*/^.=<>~")) + +;;}}} +;;{{{ var. constans + +(defconst lua-cont-eol-regexp + (eval-when-compile + ;; expression used to generate the regexp + (concat + "\\(\\<" + (regexp-opt '("and" "or" "not" "in" "for" "while" + "local" "function") t) + "\\>\\|" + "\\(^\\|[^" lua-operator-class "]\\)" + (regexp-opt '("+" "-" "*" "/" "^" ".." "==" "=" "<" ">" "<=" ">=" "~=") t) + "\\)" + "\\s *\\=") + + )) + + +(defconst lua-cont-bol-regexp + (eval-when-compile + ;; expression used to generate the regexp + (concat + "\\=\\s *" + "\\(\\<" + (regexp-opt '("and" "or" "not") t) + "\\>\\|" + (regexp-opt '("+" "-" "*" "/" "^" ".." "==" "=" "<" ">" "<=" ">=" "~=") t) + "\\($\\|[^" lua-operator-class "]\\)" + "\\)") + + )) + +;;}}} +;;{{{ lua-last-token-continues-p + +(defun lua-last-token-continues-p () + "Returns true if the last token on this line is a continuation token." + (let (line-begin + line-end) + (save-excursion + (beginning-of-line) + (setq line-begin (point)) + (end-of-line) + (setq line-end (point)) + ;; we need to check whether the line ends in a comment and + ;; skip that one. + (while (lua-find-regexp 'backward "-" line-begin 'lua-string-p) + (if (looking-at "--") + (setq line-end (point)))) + (goto-char line-end) + (re-search-backward lua-cont-eol-regexp line-begin t)))) + +;;}}} +;;{{{ lua-first-token-continues-p + +(defun lua-first-token-continues-p () + "Returns true if the first token on this line is a continuation token." + (let (line-end) + (save-excursion + (end-of-line) + (setq line-end (point)) + (beginning-of-line) + (re-search-forward lua-cont-bol-regexp line-end t)))) + +;;}}} +;;{{{ lua-is-continuing-statement-p + +(defun lua-is-continuing-statement-p (&optional parse-start) + "Return nonnil if the line continues a statement. +More specifically, return the point in the line that is continued. +The criteria for a continuing statement are: + +* the last token of the previous line is a continuing op, + OR the first token of the current line is a continuing op + +" + (let ((prev-line nil)) + (save-excursion + (if parse-start (goto-char parse-start)) + (save-excursion (setq prev-line (lua-goto-nonblank-previous-line))) + (and prev-line + (or (lua-first-token-continues-p) + (and (goto-char prev-line) + ;; check last token of previous nonblank line + (lua-last-token-continues-p))))))) + +;;}}} +;;{{{ lua-make-indentation-info-pair + +(defun lua-make-indentation-info-pair () + "This is a helper function to lua-calculate-indentation-info. Don't +use standalone." + (cond ((string-equal found-token "function") + ;; this is the location where we need to start searching for the + ;; matching opening token, when we encounter the next closing token. + ;; It is primarily an optimization to save some searchingt ime. + (cons 'absolute (+ (save-excursion (goto-char found-pos) + (current-column)) + lua-indent-level))) + ((or (string-equal found-token "{") + (string-equal found-token "(")) + (save-excursion + ;; expression follows -> indent at start of next expression + (if (and (not (search-forward-regexp "[[:space:]]--" (line-end-position) t)) + (search-forward-regexp "[^[:space:]]" (line-end-position) t)) + (cons 'absolute (1- (current-column))) + (cons 'relative lua-indent-level)))) + ;; closing tokens follow + ((string-equal found-token "end") + (save-excursion + (lua-goto-matching-block-token nil found-pos) + (if (looking-at "\\") + (cons 'absolute + (+ (current-indentation) + (lua-calculate-indentation-block-modifier + nil (point)))) + (cons 'relative (- lua-indent-level))))) + ((or (string-equal found-token ")") + (string-equal found-token "}")) + (save-excursion + (lua-goto-matching-block-token nil found-pos) + (cons 'absolute + (+ (current-indentation) + (lua-calculate-indentation-block-modifier + nil (point)))))) + (t + (cons 'relative (if (nth 2 (match-data)) + ;; beginning of a block matched + lua-indent-level + ;; end of a block matched + (- lua-indent-level)))))) + + +;;}}} +;;{{{ lua-calculate-indentation-info + +(defun lua-calculate-indentation-info (&optional parse-start parse-end) + "For each block token on the line, computes how it affects the indentation. +The effect of each token can be either a shift relative to the current +indentation level, or indentation to some absolute column. This information +is collected in a list of indentation info pairs, which denote absolute +and relative each, and the shift/column to indent to." + (let* ((line-end (save-excursion (end-of-line) (point))) + (search-stop (if parse-end (min parse-end line-end) line-end)) + (indentation-info nil)) + (if parse-start (goto-char parse-start)) + (save-excursion + (beginning-of-line) + (while (lua-find-regexp 'forward lua-indentation-modifier-regexp + search-stop) + (let ((found-token (match-string 0)) + (found-pos (match-beginning 0)) + (found-end (match-end 0)) + (data (match-data))) + (setq indentation-info + (cons (lua-make-indentation-info-pair) indentation-info))))) + indentation-info)) + +;;}}} +;;{{{ lua-accumulate-indentation-info + +(defun lua-accumulate-indentation-info (info) + "Accumulates the indentation information previously calculated by +lua-calculate-indentation-info. Returns either the relative indentation +shift, or the absolute column to indent to." + (let ((info-list (reverse info)) + (type 'relative) + (accu 0)) + (mapcar (lambda (x) + (setq accu (if (eq 'absolute (car x)) + (progn (setq type 'absolute) + (cdr x)) + (+ accu (cdr x))))) + info-list) + (cons type accu))) + +;;}}} +;;{{{ lua-calculate-indentation-block-modifier + +(defun lua-calculate-indentation-block-modifier (&optional parse-start + parse-end) + "Return amount by which this line modifies the indentation. +Beginnings of blocks add lua-indent-level once each, and endings +of blocks subtract lua-indent-level once each. This function is used +to determine how the indentation of the following line relates to this +one." + (if parse-start (goto-char parse-start)) + (let ((case-fold-search nil) + (indentation-info (lua-accumulate-indentation-info + (lua-calculate-indentation-info nil parse-end)))) + (if (eq (car indentation-info) 'absolute) + (- (cdr indentation-info) + (current-indentation) + ;; reduce indentation if this line also starts new continued statement + ;; or next line cont. this line + ;;This is for aesthetic reasons: the indentation should be + ;;dosomething(d + + ;; e + f + g) + ;;not + ;;dosomething(d + + ;; e + f + g)" + (save-excursion + (or (and (lua-last-token-continues-p) lua-indent-level) + (and (lua-goto-nonblank-next-line) (lua-first-token-continues-p) lua-indent-level) + 0))) + (+ (lua-calculate-indentation-left-shift) + (cdr indentation-info) + (if (lua-is-continuing-statement-p) (- lua-indent-level) 0))))) +;;}}} +;;{{{ constants + +(defconst lua-left-shift-regexp-1 + (concat "\\(" + "\\(\\<" (regexp-opt '("else" "elseif" "until") t) + "\\>\\)\\($\\|\\s +\\)" + "\\)")) + +(defconst lua-left-shift-regexp-2 + (concat "\\(\\<" + (regexp-opt '("end") t) + "\\>\\)")) + + +(defconst lua-left-shift-regexp + ;; This is the code we used to generate the regexp: + ;; ("else", "elseif", "until" followed by whitespace, or "end"/closing + ;; brackets followed by + ;; whitespace, punctuation, or closing parentheses) + (concat lua-left-shift-regexp-1 + "\\|\\(\\(" + lua-left-shift-regexp-2 + "\\|\\(" + (regexp-opt '("]" "}" ")")) + "\\)\\)\\($\\|\\(\\s \\|\\s.\\)*\\)" + "\\)")) + +(defconst lua-left-shift-pos-1 + 2) + +(defconst lua-left-shift-pos-2 + (+ 3 (regexp-opt-depth lua-left-shift-regexp-1))) + +(defconst lua-left-shift-pos-3 + (+ lua-left-shift-pos-2 + (regexp-opt-depth lua-left-shift-regexp-2))) + +;;}}} +;;{{{ lua-calculate-indentation-left-shift + +(defun lua-calculate-indentation-left-shift (&optional parse-start) + "Return amount, by which this line should be shifted left. +Look for an uninterrupted sequence of block-closing tokens that starts +at the beginning of the line. For each of these tokens, shift indentation +to the left by the amount specified in lua-indent-level." + (let (line-begin + (indentation-modifier 0) + (case-fold-search nil) + (block-token nil)) + (save-excursion + (if parse-start (goto-char parse-start)) + (beginning-of-line) + (setq line-begin (point)) + ;; Look for the block-closing token sequence + (skip-chars-forward lua-indent-whitespace) + (catch 'stop + (while (and (looking-at lua-left-shift-regexp) + (not (lua-comment-or-string-p))) + (let ((last-token (or (match-string lua-left-shift-pos-1) + (match-string lua-left-shift-pos-2) + (match-string lua-left-shift-pos-3)))) + (if (not block-token) (setq block-token last-token)) + (if (not (string-equal block-token last-token)) (throw 'stop nil)) + (setq indentation-modifier (+ indentation-modifier + lua-indent-level)) + (forward-char (length (match-string 0)))))) + indentation-modifier))) + +;;}}} +;;{{{ lua-calculate-indentation + +(defun lua-calculate-indentation (&optional parse-start) + "Return appropriate indentation for current line as Lua code. +In usual case returns an integer: the column to indent to." + (let ((pos (point)) + shift-amt) + (save-excursion + (if parse-start (setq pos (goto-char parse-start))) + (beginning-of-line) + (setq shift-amt (if (lua-is-continuing-statement-p) lua-indent-level 0)) + (if (bobp) ; If we're at the beginning of the buffer, no change. + (+ (current-indentation) shift-amt) + ;; This code here searches backwards for a "block beginning/end" + ;; It snarfs the indentation of that, plus whatever amount the + ;; line was shifted left by, because of block end tokens. It + ;; then adds the indentation modifier of that line to obtain the + ;; final level of indentation. + ;; Finally, if this line continues a statement from the + ;; previous line, add another level of indentation. + (if (lua-backwards-to-block-begin-or-end) + ;; now we're at the line with block beginning or end. + (max (+ (current-indentation) + (lua-calculate-indentation-block-modifier) + shift-amt) + 0) + ;; Failed to find a block begin/end. + ;; Just use the previous line's indent. + (goto-char pos) + (beginning-of-line) + (forward-line -1) + (+ (current-indentation) shift-amt)))))) + +;;}}} +;;{{{ lua-beginning-of-proc + +(defun lua-beginning-of-proc (&optional arg) + "Move backward to the beginning of a lua proc (or similar). +With argument, do it that many times. Negative arg -N +means move forward to Nth following beginning of proc. +Returns t unless search stops due to beginning or end of buffer." + (interactive "P") + (or arg + (setq arg 1)) + (let ((found nil) + (ret t)) + (if (and (< arg 0) + (looking-at "^function[ \t]")) + (forward-char 1)) + (while (< arg 0) + (if (re-search-forward "^function[ \t]" nil t) + (setq arg (1+ arg) + found t) + (setq ret nil + arg 0))) + (if found + (beginning-of-line)) + (while (> arg 0) + (if (re-search-backward "^function[ \t]" nil t) + (setq arg (1- arg)) + (setq ret nil + arg 0))) + ret)) + +;;}}} +;;{{{ lua-end-of-proc + +(defun lua-end-of-proc (&optional arg) + "Move forward to next end of lua proc (or similar). +With argument, do it that many times. Negative argument -N means move +back to Nth preceding end of proc. + +This function just searches for a `end' at the beginning of a line." + (interactive "P") + (or arg + (setq arg 1)) + (let ((found nil) + (ret t)) + (if (and (< arg 0) + (not (bolp)) + (save-excursion + (beginning-of-line) + (eq (following-char) ?}))) + (forward-char -1)) + (while (> arg 0) + (if (re-search-forward "^end" nil t) + (setq arg (1- arg) + found t) + (setq ret nil + arg 0))) + (while (< arg 0) + (if (re-search-backward "^end" nil t) + (setq arg (1+ arg) + found t) + (setq ret nil + arg 0))) + (if found + (end-of-line)) + ret)) + +;;}}} +;;{{{ lua-start-process + +(defun lua-start-process (name &optional program startfile &rest switches) + "Start a lua process named NAME, running PROGRAM." + (or switches + (setq switches lua-default-command-switches)) + (setq program (or program name)) + (setq lua-process-buffer (apply 'make-comint name program startfile switches)) + (setq lua-process (get-buffer-process lua-process-buffer)) + ;; wait for prompt + (with-current-buffer lua-process-buffer + (while (not (lua-prompt-line)) + (accept-process-output (get-buffer-process (current-buffer))) + (goto-char (point-max))))) + +;;}}} +;;{{{ lua-kill-process + +(defun lua-kill-process () + "Kill lua subprocess and its buffer." + (interactive) + (if lua-process-buffer + (kill-buffer lua-process-buffer))) + +;;}}} +;;{{{ lua-set-lua-region-start + +(defun lua-set-lua-region-start (&optional arg) + "Set start of region for use with `lua-send-lua-region'." + (interactive) + (set-marker lua-region-start (or arg (point)))) + +;;}}} +;;{{{ lua-set-lua-region-end + +(defun lua-set-lua-region-end (&optional arg) + "Set end of region for use with `lua-send-lua-region'." + (interactive) + (set-marker lua-region-end (or arg (point)))) + +;;}}} +;;{{{ lua-send-current-line + +(defun lua-send-current-line () + "Send current line to lua subprocess, found in `lua-process'. +If `lua-process' is nil or dead, start a new process first." + (interactive) + (let ((start (save-excursion (beginning-of-line) (point))) + (end (save-excursion (end-of-line) (point)))) + (lua-send-region start end))) + +;;}}} +;;{{{ lua-send-region + +(defun lua-send-region (start end) + "Send region to lua subprocess." + (interactive "r") + ;; make temporary lua file + (let ((tempfile (lua-make-temp-file "lua-")) + (last-prompt nil) + (prompt-found nil) + (lua-stdin-line-offset (count-lines (point-min) start)) + (lua-stdin-buffer (current-buffer)) + current-prompt ) + (write-region start end tempfile) + (or (and lua-process + (comint-check-proc lua-process-buffer)) + (lua-start-process lua-default-application)) + ;; kill lua process without query + (if (fboundp 'process-kill-without-query) + (process-kill-without-query lua-process)) + ;; send dofile(tempfile) + (with-current-buffer lua-process-buffer + (goto-char (point-max)) + (setq last-prompt (point-max)) + (comint-simple-send (get-buffer-process (current-buffer)) + (format "dofile(\"%s\")" + (replace-in-string tempfile "\\\\" "\\\\\\\\" ))) + ;; wait for prompt + (while (not prompt-found) + (accept-process-output (get-buffer-process (current-buffer))) + (goto-char (point-max)) + (setq prompt-found (and (lua-prompt-line) (< last-prompt (point-max))))) + ;; remove temp. lua file + (delete-file tempfile) + (lua-postprocess-output-buffer lua-process-buffer last-prompt lua-stdin-line-offset) + (if lua-always-show + (display-buffer lua-process-buffer))))) + +;;}}} +;;{{{ lua-postprocess-output-buffer + +(defun lua-postprocess-output-buffer (buf start &optional lua-stdin-line-offset) + "Highlight tracebacks found in buf. If an traceback occurred return +t, otherwise return nil. BUF must exist." + (let ((lua-stdin-line-offset (or lua-stdin-line-offset 0)) + line file bol err-p) + (save-excursion + (set-buffer buf) + (goto-char start) + (beginning-of-line) + (if (re-search-forward lua-traceback-line-re nil t) + (setq file (match-string 1) + line (string-to-int (match-string 2))))) + (when (and lua-jump-on-traceback line) + (beep) + ;; TODO: highlight + (lua-jump-to-traceback file line lua-stdin-line-offset) + (setq err-p t)) + err-p)) + +;;}}} +;;{{{ lua-jump-to-tracebackw + +(defun lua-jump-to-traceback (file line lua-stdin-line-offset) + "Jump to the Lua code in FILE at LINE." + ;; sanity check: temporary-file-directory + (if (string= (substring file 0 3) "...") + (message "Lua traceback output truncated: customize 'temporary-file-directory' or increase 'LUA_IDSIZE' in 'luaconf.h'.") + (let ((buffer (cond ((or (string-equal file tempfile) (string-equal file "stdin")) + (setq line (+ line lua-stdin-line-offset)) + lua-stdin-buffer) + (t (find-file-noselect file))))) + (pop-to-buffer buffer) + ;; Force Lua mode + (if (not (eq major-mode 'lua-mode)) + (lua-mode)) + ;; TODO fix offset when executing region + (goto-line line) + (message "Jumping to error in file %s on line %d" file line)))) + +;;}}} +;;{{{ lua-prompt-line + +(defun lua-prompt-line () + (save-excursion + (save-match-data + (forward-line 0) + (if (looking-at comint-prompt-regexp) + (match-end 0))))) + +;;{{{ lua-send-lua-region +;;}}} + +(defun lua-send-lua-region () + "Send preset lua region to lua subprocess." + (interactive) + (or (and lua-region-start lua-region-end) + (error "lua-region not set")) + (or (and lua-process + (comint-check-proc lua-process-buffer)) + (lua-start-process lua-default-application)) + (comint-simple-send lua-process + (buffer-substring lua-region-start lua-region-end) +) + (if lua-always-show + (display-buffer lua-process-buffer))) + +;;}}} +;;{{{ lua-send-proc + +(defun lua-send-proc () + "Send proc around point to lua subprocess." + (interactive) + (let (beg end) + (save-excursion + (lua-beginning-of-proc) + (setq beg (point)) + (lua-end-of-proc) + (setq end (point))) + (or (and lua-process + (comint-check-proc lua-process-buffer)) + (lua-start-process lua-default-application)) + (comint-simple-send lua-process + (buffer-substring beg end)) + (if lua-always-show + (display-buffer lua-process-buffer)))) + +;;}}} +;;{{{ lua-send-buffer + +; This needs work... -Bret +(defun lua-send-buffer () + "Send whole buffer to lua subprocess." + (interactive) + (lua-send-region (point-min) (point-max))) + +;;}}} +;;{{{ lua-restart-with-whole-file + +(defun lua-restart-with-whole-file () + "Restart lua subprocess and send whole file as input." + (interactive) + (lua-kill-process) + (lua-start-process lua-default-application) + (lua-send-buffer)) + +;;}}} +;;{{{ lua-show-process-buffer + +(defun lua-show-process-buffer () + "Make sure `lua-process-buffer' is being displayed." + (interactive) + (display-buffer lua-process-buffer)) + +;;}}} +;;{{{ lua-hide-process-buffer + +(defun lua-hide-process-buffer () + "Delete all windows that display `lua-process-buffer'." + (interactive) + (delete-windows-on lua-process-buffer)) + +;;}}} +;;{{{ lua-search-documentation + +(defun lua-search-documentation () + "Search Lua documentation for the word at the point." + (interactive) + (browse-url (concat lua-search-url-prefix (current-word t)))) + +;;}}} +;;{{{ lua-calculate-state + +(defun lua-calculate-state (arg prevstate) + ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If + ;; arg is nil or zero, toggle the state. If arg is negative, turn + ;; the state off, and if arg is positive, turn the state on + (if (or (not arg) + (zerop (setq arg (prefix-numeric-value arg)))) + (not prevstate) + (> arg 0))) + +;;}}} +;;{{{ lua-toggle-electric-state + +(defun lua-toggle-electric-state (&optional arg) + "Toggle the electric indentation feature. +Optional numeric ARG, if supplied, turns on electric indentation when +positive, turns it off when negative, and just toggles it when zero or +left out." + (interactive "P") + (setq lua-electric-flag (lua-calculate-state arg lua-electric-flag))) + +;;}}} +;;{{{ lua-forward-sexp + +(defun lua-forward-sexp (&optional count) + "Forward to block end" + (interactive "p") + (save-match-data + (let* ((count (or count 1)) + (stackheight 0) + (block-start (mapcar 'car lua-sexp-alist)) + (block-end (mapcar 'cdr lua-sexp-alist)) + (block-regex (regexp-opt (append block-start block-end) 'words)) + current-exp + ) + (while (> count 0) + ;; skip whitespace + (skip-chars-forward " \t\n") + (if (looking-at (regexp-opt block-start 'words)) + (let ((keyword (match-string 1))) + (lua-find-matching-token-word keyword nil)) + ;; If the current keyword is not a "begin" keyword, then just + ;; perform the normal forward-sexp. + (forward-sexp 1)) + (setq count (1- count)))))) + + +;;}}} +;;{{{ menu bar + +(define-key lua-mode-menu [restart-with-whole-file] + '("Restart With Whole File" . lua-restart-with-whole-file)) +(define-key lua-mode-menu [kill-process] + '("Kill Process" . lua-kill-process)) + +(define-key lua-mode-menu [hide-process-buffer] + '("Hide Process Buffer" . lua-hide-process-buffer)) +(define-key lua-mode-menu [show-process-buffer] + '("Show Process Buffer" . lua-show-process-buffer)) + +(define-key lua-mode-menu [end-of-proc] + '("End Of Proc" . lua-end-of-proc)) +(define-key lua-mode-menu [beginning-of-proc] + '("Beginning Of Proc" . lua-beginning-of-proc)) + +(define-key lua-mode-menu [send-lua-region] + '("Send Lua-Region" . lua-send-lua-region)) +(define-key lua-mode-menu [set-lua-region-end] + '("Set Lua-Region End" . lua-set-lua-region-end)) +(define-key lua-mode-menu [set-lua-region-start] + '("Set Lua-Region Start" . lua-set-lua-region-start)) + +(define-key lua-mode-menu [send-current-line] + '("Send Current Line" . lua-send-current-line)) +(define-key lua-mode-menu [send-region] + '("Send Region" . lua-send-region)) +(define-key lua-mode-menu [send-proc] + '("Send Proc" . lua-send-proc)) +(define-key lua-mode-menu [send-buffer] + '("Send Buffer" . lua-send-buffer)) +(define-key lua-mode-menu [search-documentation] + '("Search Documentation" . lua-search-documentation)) + +;;}}} + +(provide 'lua-mode) + + +;;{{{ Emacs local variables + +;; Local Variables: +;; folded-file: t +;; End: + +;;}}} + +;;; lua-mode.el ends here diff --git a/src/mod/legacy/languages/mod_lua/lua/Makefile b/src/mod/legacy/languages/mod_lua/lua/Makefile new file mode 100644 index 0000000000..e4a3cd6108 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/Makefile @@ -0,0 +1,182 @@ +# makefile for building Lua +# see ../INSTALL for installation instructions +# see ../Makefile and luaconf.h for further customization + +# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= + +# Your platform. See PLATS for possible values. +PLAT= none + +CC= gcc +CFLAGS= -O2 -Wall $(MYCFLAGS) +AR= ar rcu +RANLIB= ranlib +RM= rm -f +LIBS= -lm $(MYLIBS) + +MYCFLAGS= +MYLDFLAGS= +MYLIBS= + +# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE ========= + +PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris + +LUA_A= liblua.a +CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \ + lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \ + lundump.o lvm.o lzio.o +LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \ + lstrlib.o loadlib.o linit.o + +LUA_T= lua +LUA_O= lua.o + +LUAC_T= luac +LUAC_O= luac.o print.o + +ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O) +ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) +ALL_A= $(LUA_A) + +default: $(PLAT) + +all: $(ALL_T) + +o: $(ALL_O) + +a: $(ALL_A) + +$(LUA_A): $(CORE_O) $(LIB_O) + $(AR) $@ $? + $(RANLIB) $@ + +$(LUA_T): $(LUA_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS) + +$(LUAC_T): $(LUAC_O) $(LUA_A) + $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS) + +clean: + $(RM) $(ALL_T) $(ALL_O) + +depend: + @$(CC) $(CFLAGS) -MM l*.c print.c + +echo: + @echo "PLAT = $(PLAT)" + @echo "CC = $(CC)" + @echo "CFLAGS = $(CFLAGS)" + @echo "AR = $(AR)" + @echo "RANLIB = $(RANLIB)" + @echo "RM = $(RM)" + @echo "MYCFLAGS = $(MYCFLAGS)" + @echo "MYLDFLAGS = $(MYLDFLAGS)" + @echo "MYLIBS = $(MYLIBS)" + +# convenience targets for popular platforms + +none: + @echo "Please choose a platform:" + @echo " $(PLATS)" + +aix: + $(MAKE) all CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" MYLDFLAGS="-brtl -bexpall" + +ansi: + $(MAKE) all MYCFLAGS=-DLUA_ANSI + +bsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E" + +freebsd: + $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline" + +generic: + $(MAKE) all MYCFLAGS= + +linux: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses" + +macosx: + $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline" +# use this on Mac OS X 10.3- +# $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX + +mingw: + $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ + "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ + "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe + $(MAKE) "LUAC_T=luac.exe" luac.exe + +posix: + $(MAKE) all MYCFLAGS=-DLUA_USE_POSIX + +solaris: + $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-ldl" + +# list targets that do not create files (but not all makes understand .PHONY) +.PHONY: all $(PLATS) default o a clean depend echo none + +# DO NOT DELETE + +lapi.o: lapi.c lua.h luaconf.h lapi.h lobject.h llimits.h ldebug.h \ + lstate.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h \ + lundump.h lvm.h +lauxlib.o: lauxlib.c lua.h luaconf.h lauxlib.h +lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h +lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ + ltable.h +ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h +ldebug.o: ldebug.c lua.h luaconf.h lapi.h lobject.h llimits.h lcode.h \ + llex.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h lvm.h +ldo.o: ldo.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lparser.h lstring.h \ + ltable.h lundump.h lvm.h +ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h lundump.h +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ + lstate.h ltm.h lzio.h +lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h +linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h +liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h +llex.o: llex.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h ltm.h \ + lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h +lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h +lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h +loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h +lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \ + ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h +lopcodes.o: lopcodes.c lopcodes.h llimits.h lua.h luaconf.h +loslib.o: loslib.c lua.h luaconf.h lauxlib.h lualib.h +lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ + lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h \ + lfunc.h lstring.h lgc.h ltable.h +lstate.o: lstate.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h llex.h lstring.h ltable.h +lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ + ltm.h lzio.h lstring.h lgc.h +lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h +ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h +ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h +ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ + lmem.h lstring.h lgc.h ltable.h +lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h +luac.o: luac.c lua.h luaconf.h lauxlib.h ldo.h lobject.h llimits.h \ + lstate.h ltm.h lzio.h lmem.h lfunc.h lopcodes.h lstring.h lgc.h \ + lundump.h +lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ + llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h +lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ + lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h +lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ + lzio.h +print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \ + ltm.h lzio.h lmem.h lopcodes.h lundump.h + +# (end of Makefile) diff --git a/src/mod/legacy/languages/mod_lua/lua/lapi.c b/src/mod/legacy/languages/mod_lua/lua/lapi.c new file mode 100644 index 0000000000..5d5145d2eb --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lapi.c @@ -0,0 +1,1087 @@ +/* +** $Id: lapi.c,v 2.55.1.5 2008/07/04 18:41:18 roberto Exp $ +** Lua API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lapi_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" + + + +const char lua_ident[] = + "$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n" + "$Authors: " LUA_AUTHORS " $\n" + "$URL: www.lua.org $\n"; + + + +#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) + +#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject) + +#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;} + + + +static TValue *index2adr (lua_State *L, int idx) { + if (idx > 0) { + TValue *o = L->base + (idx - 1); + api_check(L, idx <= L->ci->top - L->base); + if (o >= L->top) return cast(TValue *, luaO_nilobject); + else return o; + } + else if (idx > LUA_REGISTRYINDEX) { + api_check(L, idx != 0 && -idx <= L->top - L->base); + return L->top + idx; + } + else switch (idx) { /* pseudo-indices */ + case LUA_REGISTRYINDEX: return registry(L); + case LUA_ENVIRONINDEX: { + Closure *func = curr_func(L); + sethvalue(L, &L->env, func->c.env); + return &L->env; + } + case LUA_GLOBALSINDEX: return gt(L); + default: { + Closure *func = curr_func(L); + idx = LUA_GLOBALSINDEX - idx; + return (idx <= func->c.nupvalues) + ? &func->c.upvalue[idx-1] + : cast(TValue *, luaO_nilobject); + } + } +} + + +static Table *getcurrenv (lua_State *L) { + if (L->ci == L->base_ci) /* no enclosing function? */ + return hvalue(gt(L)); /* use global table as environment */ + else { + Closure *func = curr_func(L); + return func->c.env; + } +} + + +void luaA_pushobject (lua_State *L, const TValue *o) { + setobj2s(L, L->top, o); + api_incr_top(L); +} + + +LUA_API int lua_checkstack (lua_State *L, int size) { + int res = 1; + lua_lock(L); + if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) + res = 0; /* stack overflow */ + else if (size > 0) { + luaD_checkstack(L, size); + if (L->ci->top < L->top + size) + L->ci->top = L->top + size; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to)); + api_check(from, to->ci->top - to->top >= n); + from->top -= n; + for (i = 0; i < n; i++) { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); +} + + +LUA_API void lua_setlevel (lua_State *from, lua_State *to) { + to->nCcalls = from->nCcalls; +} + + +LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; +} + + +LUA_API lua_State *lua_newthread (lua_State *L) { + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = luaE_newthread(L); + setthvalue(L, L->top, L1); + api_incr_top(L); + lua_unlock(L); + luai_userstatethread(L, L1); + return L1; +} + + + +/* +** basic stack manipulation +*/ + + +LUA_API int lua_gettop (lua_State *L) { + return cast_int(L->top - L->base); +} + + +LUA_API void lua_settop (lua_State *L, int idx) { + lua_lock(L); + if (idx >= 0) { + api_check(L, idx <= L->stack_last - L->base); + while (L->top < L->base + idx) + setnilvalue(L->top++); + L->top = L->base + idx; + } + else { + api_check(L, -(idx+1) <= (L->top - L->base)); + L->top += idx+1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); +} + + +LUA_API void lua_remove (lua_State *L, int idx) { + StkId p; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + while (++p < L->top) setobjs2s(L, p-1, p); + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_insert (lua_State *L, int idx) { + StkId p; + StkId q; + lua_lock(L); + p = index2adr(L, idx); + api_checkvalidindex(L, p); + for (q = L->top; q>p; q--) setobjs2s(L, q, q-1); + setobjs2s(L, p, L->top); + lua_unlock(L); +} + + +LUA_API void lua_replace (lua_State *L, int idx) { + StkId o; + lua_lock(L); + /* explicit test for incompatible code */ + if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) + luaG_runerror(L, "no calling environment"); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + if (idx == LUA_ENVIRONINDEX) { + Closure *func = curr_func(L); + api_check(L, ttistable(L->top - 1)); + func->c.env = hvalue(L->top - 1); + luaC_barrier(L, func, L->top - 1); + } + else { + setobj(L, o, L->top - 1); + if (idx < LUA_GLOBALSINDEX) /* function upvalue? */ + luaC_barrier(L, curr_func(L), L->top - 1); + } + L->top--; + lua_unlock(L); +} + + +LUA_API void lua_pushvalue (lua_State *L, int idx) { + lua_lock(L); + setobj2s(L, L->top, index2adr(L, idx)); + api_incr_top(L); + lua_unlock(L); +} + + + +/* +** access functions (stack -> C) +*/ + + +LUA_API int lua_type (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); +} + + +LUA_API const char *lua_typename (lua_State *L, int t) { + UNUSED(L); + return (t == LUA_TNONE) ? "no value" : luaT_typenames[t]; +} + + +LUA_API int lua_iscfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return iscfunction(o); +} + + +LUA_API int lua_isnumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + return tonumber(o, &n); +} + + +LUA_API int lua_isstring (lua_State *L, int idx) { + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); +} + + +LUA_API int lua_isuserdata (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); +} + + +LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { + StkId o1 = index2adr(L, index1); + StkId o2 = index2adr(L, index2); + return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaO_rawequalObj(o1, o2); +} + + +LUA_API int lua_equal (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2); + lua_unlock(L); + return i; +} + + +LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { + StkId o1, o2; + int i; + lua_lock(L); /* may call tag method */ + o1 = index2adr(L, index1); + o2 = index2adr(L, index2); + i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 + : luaV_lessthan(L, o1, o2); + lua_unlock(L); + return i; +} + + + +LUA_API lua_Number lua_tonumber (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) + return nvalue(o); + else + return 0; +} + + +LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) { + TValue n; + const TValue *o = index2adr(L, idx); + if (tonumber(o, &n)) { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + return res; + } + else + return 0; +} + + +LUA_API int lua_toboolean (lua_State *L, int idx) { + const TValue *o = index2adr(L, idx); + return !l_isfalse(o); +} + + +LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { + StkId o = index2adr(L, idx); + if (!ttisstring(o)) { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2adr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); +} + + +LUA_API size_t lua_objlen (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TSTRING: return tsvalue(o)->len; + case LUA_TUSERDATA: return uvalue(o)->len; + case LUA_TTABLE: return luaH_getn(hvalue(o)); + case LUA_TNUMBER: { + size_t l; + lua_lock(L); /* `luaV_tostring' may create a new string */ + l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0); + lua_unlock(L); + return l; + } + default: return 0; + } +} + + +LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; +} + + +LUA_API void *lua_touserdata (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TUSERDATA: return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: return pvalue(o); + default: return NULL; + } +} + + +LUA_API lua_State *lua_tothread (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); +} + + +LUA_API const void *lua_topointer (lua_State *L, int idx) { + StkId o = index2adr(L, idx); + switch (ttype(o)) { + case LUA_TTABLE: return hvalue(o); + case LUA_TFUNCTION: return clvalue(o); + case LUA_TTHREAD: return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: return NULL; + } +} + + + +/* +** push functions (C -> stack) +*/ + + +LUA_API void lua_pushnil (lua_State *L) { + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { + lua_lock(L); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) { + lua_lock(L); + luaC_checkGC(L); + setsvalue2s(L, L->top, luaS_newlstr(L, s, len)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushstring (lua_State *L, const char *s) { + if (s == NULL) + lua_pushnil(L); + else + lua_pushlstring(L, s, strlen(s)); +} + + +LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, + va_list argp) { + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; +} + + +LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; +} + + +LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { + Closure *cl; + lua_lock(L); + luaC_checkGC(L); + api_checknelems(L, n); + cl = luaF_newCclosure(L, n, getcurrenv(L)); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top+n); + setclvalue(L, L->top, cl); + lua_assert(iswhite(obj2gco(cl))); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushboolean (lua_State *L, int b) { + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_pushthread (lua_State *L) { + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); +} + + + +/* +** get functions (Lua -> stack) +*/ + + +LUA_API void lua_gettable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); +} + + +LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_gettable(L, t, &key, L->top); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_rawget (lua_State *L, int idx) { + StkId t; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); +} + + +LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2s(L, L->top, luaH_getnum(hvalue(o), n)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { + lua_lock(L); + luaC_checkGC(L); + sethvalue(L, L->top, luaH_new(L, narray, nrec)); + api_incr_top(L); + lua_unlock(L); +} + + +LUA_API int lua_getmetatable (lua_State *L, int objindex) { + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2adr(L, objindex); + switch (ttype(obj)) { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttype(obj)]; + break; + } + if (mt == NULL) + res = 0; + else { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; +} + + +LUA_API void lua_getfenv (lua_State *L, int idx) { + StkId o; + lua_lock(L); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + switch (ttype(o)) { + case LUA_TFUNCTION: + sethvalue(L, L->top, clvalue(o)->c.env); + break; + case LUA_TUSERDATA: + sethvalue(L, L->top, uvalue(o)->env); + break; + case LUA_TTHREAD: + setobj2s(L, L->top, gt(thvalue(o))); + break; + default: + setnilvalue(L->top); + break; + } + api_incr_top(L); + lua_unlock(L); +} + + +/* +** set functions (stack -> Lua) +*/ + + +LUA_API void lua_settable (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); +} + + +LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { + StkId t; + TValue key; + lua_lock(L); + api_checknelems(L, 1); + t = index2adr(L, idx); + api_checkvalidindex(L, t); + setsvalue(L, &key, luaS_new(L, k)); + luaV_settable(L, t, &key, L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); +} + + +LUA_API void lua_rawset (lua_State *L, int idx) { + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); + luaC_barriert(L, hvalue(t), L->top-1); + L->top -= 2; + lua_unlock(L); +} + + +LUA_API void lua_rawseti (lua_State *L, int idx, int n) { + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_check(L, ttistable(o)); + setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); + luaC_barriert(L, hvalue(o), L->top-1); + L->top--; + lua_unlock(L); +} + + +LUA_API int lua_setmetatable (lua_State *L, int objindex) { + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2adr(L, objindex); + api_checkvalidindex(L, obj); + if (ttisnil(L->top - 1)) + mt = NULL; + else { + api_check(L, ttistable(L->top - 1)); + mt = hvalue(L->top - 1); + } + switch (ttype(obj)) { + case LUA_TTABLE: { + hvalue(obj)->metatable = mt; + if (mt) + luaC_objbarriert(L, hvalue(obj), mt); + break; + } + case LUA_TUSERDATA: { + uvalue(obj)->metatable = mt; + if (mt) + luaC_objbarrier(L, rawuvalue(obj), mt); + break; + } + default: { + G(L)->mt[ttype(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; +} + + +LUA_API int lua_setfenv (lua_State *L, int idx) { + StkId o; + int res = 1; + lua_lock(L); + api_checknelems(L, 1); + o = index2adr(L, idx); + api_checkvalidindex(L, o); + api_check(L, ttistable(L->top - 1)); + switch (ttype(o)) { + case LUA_TFUNCTION: + clvalue(o)->c.env = hvalue(L->top - 1); + break; + case LUA_TUSERDATA: + uvalue(o)->env = hvalue(L->top - 1); + break; + case LUA_TTHREAD: + sethvalue(L, gt(thvalue(o)), hvalue(L->top - 1)); + break; + default: + res = 0; + break; + } + if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + L->top--; + lua_unlock(L); + return res; +} + + +/* +** `load' and `call' functions (run Lua code) +*/ + + +#define adjustresults(L,nres) \ + { if (nres == LUA_MULTRET && L->top >= L->ci->top) L->ci->top = L->top; } + + +#define checkresults(L,na,nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) + + +LUA_API void lua_call (lua_State *L, int nargs, int nresults) { + StkId func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + func = L->top - (nargs+1); + luaD_call(L, func, nresults); + adjustresults(L, nresults); + lua_unlock(L); +} + + + +/* +** Execute a protected call. +*/ +struct CallS { /* data to `f_call' */ + StkId func; + int nresults; +}; + + +static void f_call (lua_State *L, void *ud) { + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults); +} + + + +LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) { + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_checknelems(L, nargs+1); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else { + StkId o = index2adr(L, errfunc); + api_checkvalidindex(L, o); + func = savestack(L, o); + } + c.func = L->top - (nargs+1); /* function to be called */ + c.nresults = nresults; + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + adjustresults(L, nresults); + lua_unlock(L); + return status; +} + + +/* +** Execute a protected C call. +*/ +struct CCallS { /* data to `f_Ccall' */ + lua_CFunction func; + void *ud; +}; + + +static void f_Ccall (lua_State *L, void *ud) { + struct CCallS *c = cast(struct CCallS *, ud); + Closure *cl; + cl = luaF_newCclosure(L, 0, getcurrenv(L)); + cl->c.f = c->func; + setclvalue(L, L->top, cl); /* push function */ + api_incr_top(L); + setpvalue(L->top, c->ud); /* push only argument */ + api_incr_top(L); + luaD_call(L, L->top - 2, 0); +} + + +LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { + struct CCallS c; + int status; + lua_lock(L); + c.func = func; + c.ud = ud; + status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0); + lua_unlock(L); + return status; +} + + +LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, + const char *chunkname) { + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname); + lua_unlock(L); + return status; +} + + +LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; +} + + +LUA_API int lua_status (lua_State *L) { + return L->status; +} + + +/* +** Garbage-collection function +*/ + +LUA_API int lua_gc (lua_State *L, int what, int data) { + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) { + case LUA_GCSTOP: { + g->GCthreshold = MAX_LUMEM; + break; + } + case LUA_GCRESTART: { + g->GCthreshold = g->totalbytes; + break; + } + case LUA_GCCOLLECT: { + luaC_fullgc(L); + break; + } + case LUA_GCCOUNT: { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(g->totalbytes >> 10); + break; + } + case LUA_GCCOUNTB: { + res = cast_int(g->totalbytes & 0x3ff); + break; + } + case LUA_GCSTEP: { + lu_mem a = (cast(lu_mem, data) << 10); + if (a <= g->totalbytes) + g->GCthreshold = g->totalbytes - a; + else + g->GCthreshold = 0; + while (g->GCthreshold <= g->totalbytes) { + luaC_step(L); + if (g->gcstate == GCSpause) { /* end of cycle? */ + res = 1; /* signal it */ + break; + } + } + break; + } + case LUA_GCSETPAUSE: { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETSTEPMUL: { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + default: res = -1; /* invalid option */ + } + lua_unlock(L); + return res; +} + + + +/* +** miscellaneous functions +*/ + + +LUA_API int lua_error (lua_State *L) { + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + lua_unlock(L); + return 0; /* to avoid warnings */ +} + + +LUA_API int lua_next (lua_State *L, int idx) { + StkId t; + int more; + lua_lock(L); + t = index2adr(L, idx); + api_check(L, ttistable(t)); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; +} + + +LUA_API void lua_concat (lua_State *L, int n) { + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) { + luaC_checkGC(L); + luaV_concat(L, n, cast_int(L->top - L->base) - 1); + L->top -= (n-1); + } + else if (n == 0) { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); +} + + +LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; +} + + +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); +} + + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, getcurrenv(L)); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; +} + + + + +static const char *aux_upvalue (StkId fi, int n, TValue **val) { + Closure *f; + if (!ttisfunction(fi)) return NULL; + f = clvalue(fi); + if (f->c.isC) { + if (!(1 <= n && n <= f->c.nupvalues)) return NULL; + *val = &f->c.upvalue[n-1]; + return ""; + } + else { + Proto *p = f->l.p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->l.upvals[n-1]->v; + return getstr(p->upvalues[n-1]); + } +} + + +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + lua_lock(L); + name = aux_upvalue(index2adr(L, funcindex), n, &val); + if (name) { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { + const char *name; + TValue *val; + StkId fi; + lua_lock(L); + fi = index2adr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val); + if (name) { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, clvalue(fi), L->top); + } + lua_unlock(L); + return name; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lapi.h b/src/mod/legacy/languages/mod_lua/lua/lapi.h new file mode 100644 index 0000000000..2c3fab244e --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lapi.h @@ -0,0 +1,16 @@ +/* +** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "lobject.h" + + +LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o); + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lauxlib.c b/src/mod/legacy/languages/mod_lua/lua/lauxlib.c new file mode 100644 index 0000000000..10f14e2c08 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lauxlib.c @@ -0,0 +1,652 @@ +/* +** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include +#include + + +/* This file uses only the official API of Lua. +** Any function declared here could be written as an application function. +*/ + +#define lauxlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" + + +#define FREELIST_REF 0 /* free list of references */ + + +/* convert a stack index to positive */ +#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ + lua_gettop(L) + (i) + 1) + + +/* +** {====================================================== +** Error-report functions +** ======================================================= +*/ + + +LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); +} + + +LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} + + +static void tag_error (lua_State *L, int narg, int tag) { + luaL_typerror(L, narg, lua_typename(L, tag)); +} + + +LUALIB_API void luaL_where (lua_State *L, int level) { + lua_Debug ar; + if (lua_getstack(L, level, &ar)) { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ +} + + +LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); +} + +/* }====================================================== */ + + +LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, + const char *const lst[]) { + const char *name = (def) ? luaL_optstring(L, narg, def) : + luaL_checkstring(L, narg); + int i; + for (i=0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); +} + + +LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; +} + + +LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { + void *p = lua_touserdata(L, ud); + if (p != NULL) { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */ + if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + } + luaL_typerror(L, ud, tname); /* else error */ + return NULL; /* to avoid warnings */ +} + + +LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { + if (!lua_checkstack(L, space)) + luaL_error(L, "stack overflow (%s)", mes); +} + + +LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { + if (lua_type(L, narg) != t) + tag_error(L, narg, t); +} + + +LUALIB_API void luaL_checkany (lua_State *L, int narg) { + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); +} + + +LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; +} + + +LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, + const char *def, size_t *len) { + if (lua_isnoneornil(L, narg)) { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else return luaL_checklstring(L, narg, len); +} + + +LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { + lua_Number d = lua_tonumber(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { + return luaL_opt(L, luaL_checknumber, narg, def); +} + + +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + lua_Integer d = lua_tointeger(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + return luaL_opt(L, luaL_checkinteger, narg, def); +} + + +LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } +} + + +LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { + obj = abs_index(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; +} + + +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l) { + luaI_openlib(L, libname, l, 0); +} + + +static int libsize (const luaL_Reg *l) { + int size = 0; + for (; l->name; l++) size++; + return size; +} + + +LUALIB_API void luaI_openlib (lua_State *L, const char *libname, + const luaL_Reg *l, int nup) { + if (libname) { + int size = libsize(l); + /* check whether lib already exists */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); + lua_getfield(L, -1, libname); /* get _LOADED[libname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, libname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ + lua_insert(L, -(nup+1)); /* move library table to below upvalues */ + } + for (; l->name; l++) { + int i; + for (i=0; ifunc, nup); + lua_setfield(L, -(nup+2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ +} + + + +/* +** {====================================================== +** getn-setn: size for arrays +** ======================================================= +*/ + +#if defined(LUA_COMPAT_GETN) + +static int checkint (lua_State *L, int topop) { + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; + lua_pop(L, topop); + return n; +} + + +static void getsizes (lua_State *L) { + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); + if (lua_isnil(L, -1)) { /* no `size' table? */ + lua_pop(L, 1); /* remove nil */ + lua_newtable(L); /* create it */ + lua_pushvalue(L, -1); /* `size' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES"); /* store in register */ + } +} + + +LUALIB_API void luaL_setn (lua_State *L, int t, int n) { + t = abs_index(L, t); + lua_pushliteral(L, "n"); + lua_rawget(L, t); + if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ + lua_pushliteral(L, "n"); /* use it */ + lua_pushinteger(L, n); + lua_rawset(L, t); + } + else { /* use `sizes' */ + getsizes(L); + lua_pushvalue(L, t); + lua_pushinteger(L, n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ + } +} + + +LUALIB_API int luaL_getn (lua_State *L, int t) { + int n; + t = abs_index(L, t); + lua_pushliteral(L, "n"); /* try t.n */ + lua_rawget(L, t); + if ((n = checkint(L, 1)) >= 0) return n; + getsizes(L); /* else try sizes[t] */ + lua_pushvalue(L, t); + lua_rawget(L, -2); + if ((n = checkint(L, 2)) >= 0) return n; + return (int)lua_objlen(L, t); +} + +#endif + +/* }====================================================== */ + + + +LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, + const char *r) { + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); +} + + +LUALIB_API const char *luaL_findtable (lua_State *L, int idx, + const char *fname, int szhint) { + const char *e; + lua_pushvalue(L, idx); + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; +} + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + +#define bufflen(B) ((B)->p - (B)->buffer) +#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) + +#define LIMIT (LUA_MINSTACK/2) + + +static int emptybuffer (luaL_Buffer *B) { + size_t l = bufflen(B); + if (l == 0) return 0; /* put nothing on stack */ + else { + lua_pushlstring(B->L, B->buffer, l); + B->p = B->buffer; + B->lvl++; + return 1; + } +} + + +static void adjuststack (luaL_Buffer *B) { + if (B->lvl > 1) { + lua_State *L = B->L; + int toget = 1; /* number of levels to concat */ + size_t toplen = lua_strlen(L, -1); + do { + size_t l = lua_strlen(L, -(toget+1)); + if (B->lvl - toget + 1 >= LIMIT || toplen > l) { + toplen += l; + toget++; + } + else break; + } while (toget < B->lvl); + lua_concat(L, toget); + B->lvl = B->lvl - toget + 1; + } +} + + +LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { + if (emptybuffer(B)) + adjuststack(B); + return B->buffer; +} + + +LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { + while (l--) + luaL_addchar(B, *s++); +} + + +LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { + luaL_addlstring(B, s, strlen(s)); +} + + +LUALIB_API void luaL_pushresult (luaL_Buffer *B) { + emptybuffer(B); + lua_concat(B->L, B->lvl); + B->lvl = 1; +} + + +LUALIB_API void luaL_addvalue (luaL_Buffer *B) { + lua_State *L = B->L; + size_t vl; + const char *s = lua_tolstring(L, -1, &vl); + if (vl <= bufffree(B)) { /* fit into buffer? */ + memcpy(B->p, s, vl); /* put it there */ + B->p += vl; + lua_pop(L, 1); /* remove from stack */ + } + else { + if (emptybuffer(B)) + lua_insert(L, -2); /* put buffer before new value */ + B->lvl++; /* add new value into B stack */ + adjuststack(B); + } +} + + +LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { + B->L = L; + B->p = B->buffer; + B->lvl = 0; +} + +/* }====================================================== */ + + +LUALIB_API int luaL_ref (lua_State *L, int t) { + int ref; + t = abs_index(L, t); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ + } + else { /* no free elements */ + ref = (int)lua_objlen(L, t); + ref++; /* create new reference */ + } + lua_rawseti(L, t, ref); + return ref; +} + + +LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { + if (ref >= 0) { + t = abs_index(L, t); + lua_rawgeti(L, t, FREELIST_REF); + lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ + } +} + + + +/* +** {====================================================== +** Load functions +** ======================================================= +*/ + +typedef struct LoadF { + int extraline; + FILE *f; + char buff[LUAL_BUFFERSIZE]; +} LoadF; + + +static const char *getF (lua_State *L, void *ud, size_t *size) { + LoadF *lf = (LoadF *)ud; + (void)L; + if (lf->extraline) { + lf->extraline = 0; + *size = 1; + return "\n"; + } + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); + return (*size > 0) ? lf->buff : NULL; +} + + +static int errfile (lua_State *L, const char *what, int fnameindex) { + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; +} + + +LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + lf.extraline = 0; + if (filename == NULL) { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + c = getc(lf.f); + if (c == '#') { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ + if (c == '\n') c = getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + /* skip eventual `#!...' */ + while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; + lf.extraline = 0; + } + ungetc(c, lf.f); + status = lua_load(L, getF, &lf, lua_tostring(L, -1)); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; +} + + +typedef struct LoadS { + const char *s; + size_t size; +} LoadS; + + +static const char *getS (lua_State *L, void *ud, size_t *size) { + LoadS *ls = (LoadS *)ud; + (void)L; + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; +} + + +LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, + const char *name) { + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name); +} + + +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) { + return luaL_loadbuffer(L, s, strlen(s), s); +} + + + +/* }====================================================== */ + + +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; + (void)osize; + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +static int panic (lua_State *L) { + (void)L; /* to avoid warnings */ + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; +} + + +LUALIB_API lua_State *luaL_newstate (void) { + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lauxlib.h b/src/mod/legacy/languages/mod_lua/lua/lauxlib.h new file mode 100644 index 0000000000..34258235db --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lauxlib.h @@ -0,0 +1,174 @@ +/* +** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "lua.h" + + +#if defined(LUA_COMPAT_GETN) +LUALIB_API int (luaL_getn) (lua_State *L, int t); +LUALIB_API void (luaL_setn) (lua_State *L, int t, int n); +#else +#define luaL_getn(L,i) ((int)lua_objlen(L, i)) +#define luaL_setn(L,i,j) ((void)0) /* no op! */ +#endif + +#if defined(LUA_COMPAT_OPENLIB) +#define luaI_openlib luaL_openlib +#endif + + +/* extra error code for `luaL_load' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + + +LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); +LUALIB_API void (luaL_register) (lua_State *L, const char *libname, + const luaL_Reg *l); +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname); +LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int narg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename); +LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, + const char *name); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + + +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, + const char *r); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname, int szhint); + + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define luaL_argcheck(L, cond,numarg,extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + + + +typedef struct luaL_Buffer { + char *p; /* current position in buffer */ + int lvl; /* number of strings in the stack (level) */ + lua_State *L; + char buffer[LUAL_BUFFERSIZE]; +} luaL_Buffer; + +#define luaL_addchar(B,c) \ + ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ + (*(B)->p++ = (char)(c))) + +/* compatibility only */ +#define luaL_putchar(B,c) luaL_addchar(B,c) + +#define luaL_addsize(B,n) ((B)->p += (n)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); + + +/* }====================================================== */ + + +/* compatibility with ref system */ + +/* pre-defined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \ + (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0)) + +#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref)) + +#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref)) + + +#define luaL_reg luaL_Reg + +#endif + + diff --git a/src/mod/legacy/languages/mod_lua/lua/lbaselib.c b/src/mod/legacy/languages/mod_lua/lua/lbaselib.c new file mode 100644 index 0000000000..2a4c079d3b --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lbaselib.c @@ -0,0 +1,653 @@ +/* +** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#define lbaselib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, LUA_QL("tostring") " must return a string to " + LUA_QL("print")); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_pop(L, 1); /* pop result */ + } + fputs("\n", stdout); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_optint(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checkany(L, 1); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_checkstring(L, 1); + char *s2; + unsigned long n; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, (lua_Number)n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); +} + + +static int luaB_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ +} + + +static int luaB_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; +} + + +static void getfunc (lua_State *L, int opt) { + if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); + else { + lua_Debug ar; + int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); + luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); + if (lua_getstack(L, level, &ar) == 0) + luaL_argerror(L, 1, "invalid level"); + lua_getinfo(L, "f", &ar); + if (lua_isnil(L, -1)) + luaL_error(L, "no function environment for tail call at level %d", + level); + } +} + + +static int luaB_getfenv (lua_State *L) { + getfunc(L, 1); + if (lua_iscfunction(L, -1)) /* is a C function? */ + lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */ + else + lua_getfenv(L, -1); + return 1; +} + + +static int luaB_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + getfunc(L, 0); + lua_pushvalue(L, 2); + if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) { + /* change environment of current thread */ + lua_pushthread(L); + lua_insert(L, -2); + lua_setfenv(L, -2); + return 0; + } + else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) + luaL_error(L, + LUA_QL("setfenv") " cannot change environment of given object"); + return 1; +} + + +static int luaB_rawequal (lua_State *L) { + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; +} + + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; +} + + +static int luaB_gcinfo (lua_State *L) { + lua_pushinteger(L, lua_getgccount(L)); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL}; + int o = luaL_checkoption(L, 1, "collect", opts); + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, optsnum[o], ex); + switch (optsnum[o]) { + case LUA_GCCOUNT: { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b/1024)); + return 1; + } + case LUA_GCSTEP: { + lua_pushboolean(L, res); + return 1; + } + default: { + lua_pushnumber(L, res); + return 1; + } + } +} + + +static int luaB_type (lua_State *L) { + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int luaB_pairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushnil(L); /* and initial value */ + return 3; +} + + +static int ipairsaux (lua_State *L) { + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 0 : 2; +} + + +static int luaB_ipairs (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */ + lua_pushvalue(L, 1); /* state, */ + lua_pushinteger(L, 0); /* and initial value */ + return 3; +} + + +static int load_aux (lua_State *L, int status) { + if (status == 0) /* OK? */ + return 1; + else { + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } +} + + +static int luaB_loadstring (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *chunkname = luaL_optstring(L, 2, s); + return load_aux(L, luaL_loadbuffer(L, s, l, chunkname)); +} + + +static int luaB_loadfile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + return load_aux(L, luaL_loadfile(L, fname)); +} + + +/* +** Reader for generic `load' function: `lua_load' uses the +** stack for internal stuff, so the reader cannot change the +** stack top. Instead, it keeps its resulting string in a +** reserved slot inside the stack. +*/ +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + (void)ud; /* to avoid warnings */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) { + *size = 0; + return NULL; + } + else if (lua_isstring(L, -1)) { + lua_replace(L, 3); /* save string in a reserved stack slot */ + return lua_tolstring(L, 3, size); + } + else luaL_error(L, "reader function must return a string"); + return NULL; /* to avoid warnings */ +} + + +static int luaB_load (lua_State *L) { + int status; + const char *cname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ + status = lua_load(L, generic_reader, NULL, cname); + return load_aux(L, status); +} + + +static int luaB_dofile (lua_State *L) { + const char *fname = luaL_optstring(L, 1, NULL); + int n = lua_gettop(L); + if (luaL_loadfile(L, fname) != 0) lua_error(L); + lua_call(L, 0, LUA_MULTRET); + return lua_gettop(L) - n; +} + + +static int luaB_assert (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); +} + + +static int luaB_unpack (lua_State *L) { + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1)); + if (i > e) return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; +} + + +static int luaB_select (lua_State *L) { + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { + lua_pushinteger(L, n-1); + return 1; + } + else { + int i = luaL_checkint(L, 1); + if (i < 0) i = n + i; + else if (i > n) i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } +} + + +static int luaB_pcall (lua_State *L) { + int status; + luaL_checkany(L, 1); + status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0); + lua_pushboolean(L, (status == 0)); + lua_insert(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_xpcall (lua_State *L) { + int status; + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_insert(L, 1); /* put error function under function to be called */ + status = lua_pcall(L, 0, LUA_MULTRET, 1); + lua_pushboolean(L, (status == 0)); + lua_replace(L, 1); + return lua_gettop(L); /* return status + all results */ +} + + +static int luaB_tostring (lua_State *L) { + luaL_checkany(L, 1); + if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ + return 1; /* use its value */ + switch (lua_type(L, 1)) { + case LUA_TNUMBER: + lua_pushstring(L, lua_tostring(L, 1)); + break; + case LUA_TSTRING: + lua_pushvalue(L, 1); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1)); + break; + } + return 1; +} + + +static int luaB_newproxy (lua_State *L) { + lua_settop(L, 1); + lua_newuserdata(L, 0); /* create proxy */ + if (lua_toboolean(L, 1) == 0) + return 1; /* no metatable */ + else if (lua_isboolean(L, 1)) { + lua_newtable(L); /* create a new metatable `m' ... */ + lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ + lua_pushboolean(L, 1); + lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ + } + else { + int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ + if (lua_getmetatable(L, 1)) { + lua_rawget(L, lua_upvalueindex(1)); + validproxy = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + } + luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); + lua_getmetatable(L, 1); /* metatable is valid; get it */ + } + lua_setmetatable(L, 2); + return 1; +} + + +static const luaL_Reg base_funcs[] = { + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"gcinfo", luaB_gcinfo}, + {"getfenv", luaB_getfenv}, + {"getmetatable", luaB_getmetatable}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, + {"loadstring", luaB_loadstring}, + {"next", luaB_next}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setfenv", luaB_setfenv}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"unpack", luaB_unpack}, + {"xpcall", luaB_xpcall}, + {NULL, NULL} +}; + + +/* +** {====================================================== +** Coroutine library +** ======================================================= +*/ + +#define CO_RUN 0 /* running */ +#define CO_SUS 1 /* suspended */ +#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */ +#define CO_DEAD 3 + +static const char *const statnames[] = + {"running", "suspended", "normal", "dead"}; + +static int costatus (lua_State *L, lua_State *co) { + if (L == co) return CO_RUN; + switch (lua_status(co)) { + case LUA_YIELD: + return CO_SUS; + case 0: { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + return CO_NOR; /* it is running */ + else if (lua_gettop(co) == 0) + return CO_DEAD; + else + return CO_SUS; /* initial state */ + } + default: /* some error occured */ + return CO_DEAD; + } +} + + +static int luaB_costatus (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + lua_pushstring(L, statnames[costatus(L, co)]); + return 1; +} + + +static int auxresume (lua_State *L, lua_State *co, int narg) { + int status = costatus(L, co); + if (!lua_checkstack(co, narg)) + luaL_error(L, "too many arguments to resume"); + if (status != CO_SUS) { + lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + lua_setlevel(L, co); + status = lua_resume(co, narg); + if (status == 0 || status == LUA_YIELD) { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) + luaL_error(L, "too many results to resume"); + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } +} + + +static int luaB_coresume (lua_State *L) { + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } +} + + +static int luaB_auxwrap (lua_State *L) { + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) { + if (lua_isstring(L, -1)) { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + lua_error(L); /* propagate error */ + } + return r; +} + + +static int luaB_cocreate (lua_State *L) { + lua_State *NL = lua_newthread(L); + luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, + "Lua function expected"); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; +} + + +static int luaB_cowrap (lua_State *L) { + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; +} + + +static int luaB_yield (lua_State *L) { + return lua_yield(L, lua_gettop(L)); +} + + +static int luaB_corunning (lua_State *L) { + if (lua_pushthread(L)) + lua_pushnil(L); /* main thread is not a coroutine */ + return 1; +} + + +static const luaL_Reg co_funcs[] = { + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL} +}; + +/* }====================================================== */ + + +static void auxopen (lua_State *L, const char *name, + lua_CFunction f, lua_CFunction u) { + lua_pushcfunction(L, u); + lua_pushcclosure(L, f, 1); + lua_setfield(L, -2, name); +} + + +static void base_open (lua_State *L) { + /* set global _G */ + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_G"); + /* open lib into global table */ + luaL_register(L, "_G", base_funcs); + lua_pushliteral(L, LUA_VERSION); + lua_setglobal(L, "_VERSION"); /* set global _VERSION */ + /* `ipairs' and `pairs' need auxliliary functions as upvalues */ + auxopen(L, "ipairs", luaB_ipairs, ipairsaux); + auxopen(L, "pairs", luaB_pairs, luaB_next); + /* `newproxy' needs a weaktable as upvalue */ + lua_createtable(L, 0, 1); /* new table `w' */ + lua_pushvalue(L, -1); /* `w' will be its own metatable */ + lua_setmetatable(L, -2); + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ + lua_pushcclosure(L, luaB_newproxy, 1); + lua_setglobal(L, "newproxy"); /* set global `newproxy' */ +} + + +LUALIB_API int luaopen_base (lua_State *L) { + base_open(L); + luaL_register(L, LUA_COLIBNAME, co_funcs); + return 2; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lcode.c b/src/mod/legacy/languages/mod_lua/lua/lcode.c new file mode 100644 index 0000000000..cff626b7fa --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lcode.c @@ -0,0 +1,839 @@ +/* +** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + + +#include + +#define lcode_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "ltable.h" + + +#define hasjumps(e) ((e)->t != (e)->f) + + +static int isnumeral(expdesc *e) { + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +} + + +void luaK_nil (FuncState *fs, int from, int n) { + Instruction *previous; + if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ + if (fs->pc == 0) { /* function start? */ + if (from >= fs->nactvar) + return; /* positions are already clean */ + } + else { + previous = &fs->f->code[fs->pc-1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) { + int pfrom = GETARG_A(*previous); + int pto = GETARG_B(*previous); + if (pfrom <= from && from <= pto+1) { /* can connect both? */ + if (from+n-1 > pto) + SETARG_B(*previous, from+n-1); + return; + } + } + } + } + luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ +} + + +int luaK_jump (FuncState *fs) { + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; +} + + +void luaK_ret (FuncState *fs, int first, int nret) { + luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +} + + +static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); +} + + +static void fixjump (FuncState *fs, int pc, int dest) { + Instruction *jmp = &fs->f->code[pc]; + int offset = dest-(pc+1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); +} + + +/* +** returns current `pc' and marks it as a jump target (to avoid wrong +** optimizations with consecutive instructions not in the same basic block). +*/ +int luaK_getlabel (FuncState *fs) { + fs->lasttarget = fs->pc; + return fs->pc; +} + + +static int getjump (FuncState *fs, int pc) { + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc+1)+offset; /* turn offset into absolute position */ +} + + +static Instruction *getjumpcontrol (FuncState *fs, int pc) { + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) + return pi-1; + else + return pi; +} + + +/* +** check whether list has any jump that do not produce a value +** (or produce an inverted value) +*/ +static int need_value (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ +} + + +static int patchtestreg (FuncState *fs, int node, int reg) { + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); + + return 1; +} + + +static void removevalues (FuncState *fs, int list) { + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); +} + + +static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, + int dtarget) { + while (list != NO_JUMP) { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } +} + + +static void dischargejpc (FuncState *fs) { + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; +} + + +void luaK_patchlist (FuncState *fs, int list, int target) { + if (target == fs->pc) + luaK_patchtohere(fs, list); + else { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } +} + + +void luaK_patchtohere (FuncState *fs, int list) { + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); +} + + +void luaK_concat (FuncState *fs, int *l1, int l2) { + if (l2 == NO_JUMP) return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } +} + + +void luaK_checkstack (FuncState *fs, int n) { + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } +} + + +void luaK_reserveregs (FuncState *fs, int n) { + luaK_checkstack(fs, n); + fs->freereg += n; +} + + +static void freereg (FuncState *fs, int reg) { + if (!ISK(reg) && reg >= fs->nactvar) { + fs->freereg--; + lua_assert(reg == fs->freereg); + } +} + + +static void freeexp (FuncState *fs, expdesc *e) { + if (e->k == VNONRELOC) + freereg(fs, e->u.s.info); +} + + +static int addk (FuncState *fs, TValue *k, TValue *v) { + lua_State *L = fs->L; + TValue *idx = luaH_set(L, fs->h, k); + Proto *f = fs->f; + int oldsize = f->sizek; + if (ttisnumber(idx)) { + lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); + return cast_int(nvalue(idx)); + } + else { /* constant not found; create a new entry */ + setnvalue(idx, cast_num(fs->nk)); + luaM_growvector(L, f->k, fs->nk, f->sizek, TValue, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[fs->nk], v); + luaC_barrier(L, f, v); + return fs->nk++; + } +} + + +int luaK_stringK (FuncState *fs, TString *s) { + TValue o; + setsvalue(fs->L, &o, s); + return addk(fs, &o, &o); +} + + +int luaK_numberK (FuncState *fs, lua_Number r) { + TValue o; + setnvalue(&o, r); + return addk(fs, &o, &o); +} + + +static int boolK (FuncState *fs, int b) { + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); +} + + +static int nilK (FuncState *fs) { + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->L, &k, fs->h); + return addk(fs, &k, &v); +} + + +void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { + if (e->k == VCALL) { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults+1); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), nresults+1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } +} + + +void luaK_setoneret (FuncState *fs, expdesc *e) { + if (e->k == VCALL) { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.s.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } +} + + +void luaK_dischargevars (FuncState *fs, expdesc *e) { + switch (e->k) { + case VLOCAL: { + e->k = VNONRELOC; + break; + } + case VUPVAL: { + e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + case VGLOBAL: { + e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info); + e->k = VRELOCABLE; + break; + } + case VINDEXED: { + freereg(fs, e->u.s.aux); + freereg(fs, e->u.s.info); + e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: { + luaK_setoneret(fs, e); + break; + } + default: break; /* there is one value available (somewhere) */ + } +} + + +static int code_label (FuncState *fs, int A, int b, int jump) { + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +} + + +static void discharge2reg (FuncState *fs, expdesc *e, int reg) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: case VTRUE: { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: { + luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info); + break; + } + case VKNUM: { + luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: { + if (reg != e->u.s.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0); + break; + } + default: { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +static void discharge2anyreg (FuncState *fs, expdesc *e) { + if (e->k != VNONRELOC) { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg-1); + } +} + + +static void exp2reg (FuncState *fs, expdesc *e, int reg) { + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.s.info); /* put this jump in `t' list */ + if (hasjumps(e)) { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.s.info = reg; + e->k = VNONRELOC; +} + + +void luaK_exp2nextreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); +} + + +int luaK_exp2anyreg (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) { + if (!hasjumps(e)) return e->u.s.info; /* exp is already in a register */ + if (e->u.s.info >= fs->nactvar) { /* reg. is not a local? */ + exp2reg(fs, e, e->u.s.info); /* put value on it */ + return e->u.s.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.s.info; +} + + +void luaK_exp2val (FuncState *fs, expdesc *e) { + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); +} + + +int luaK_exp2RK (FuncState *fs, expdesc *e) { + luaK_exp2val(fs, e); + switch (e->k) { + case VKNUM: + case VTRUE: + case VFALSE: + case VNIL: { + if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */ + e->u.s.info = (e->k == VNIL) ? nilK(fs) : + (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) : + boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.s.info); + } + else break; + } + case VK: { + if (e->u.s.info <= MAXINDEXRK) /* constant fit in argC? */ + return RKASK(e->u.s.info); + else break; + } + default: break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); +} + + +void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { + switch (var->k) { + case VLOCAL: { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.s.info); + return; + } + case VUPVAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); + break; + } + case VGLOBAL: { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info); + break; + } + case VINDEXED: { + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); + break; + } + default: { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); +} + + +void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { + int func; + luaK_exp2anyreg(fs, e); + freeexp(fs, e); + func = fs->freereg; + luaK_reserveregs(fs, 2); + luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); + freeexp(fs, key); + e->u.s.info = func; + e->k = VNONRELOC; +} + + +static void invertjump (FuncState *fs, expdesc *e) { + Instruction *pc = getjumpcontrol(fs, e->u.s.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); +} + + +static int jumponcond (FuncState *fs, expdesc *e, int cond) { + if (e->k == VRELOCABLE) { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond); +} + + +void luaK_goiftrue (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VK: case VKNUM: case VTRUE: { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + case VFALSE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + invertjump(fs, e); + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; +} + + +static void luaK_goiffalse (FuncState *fs, expdesc *e) { + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + case VTRUE: { + pc = luaK_jump(fs); /* always jump */ + break; + } + case VJMP: { + pc = e->u.s.info; + break; + } + default: { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; +} + + +static void codenot (FuncState *fs, expdesc *e) { + luaK_dischargevars(fs, e); + switch (e->k) { + case VNIL: case VFALSE: { + e->k = VTRUE; + break; + } + case VK: case VKNUM: case VTRUE: { + e->k = VFALSE; + break; + } + case VJMP: { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0); + e->k = VRELOCABLE; + break; + } + default: { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { int temp = e->f; e->f = e->t; e->t = temp; } + removevalues(fs, e->f); + removevalues(fs, e->t); +} + + +void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { + t->u.s.aux = luaK_exp2RK(fs, k); + t->k = VINDEXED; +} + + +static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { + lua_Number v1, v2, r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + v1 = e1->u.nval; + v2 = e2->u.nval; + switch (op) { + case OP_ADD: r = luai_numadd(v1, v2); break; + case OP_SUB: r = luai_numsub(v1, v2); break; + case OP_MUL: r = luai_nummul(v1, v2); break; + case OP_DIV: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_numdiv(v1, v2); break; + case OP_MOD: + if (v2 == 0) return 0; /* do not attempt to divide by 0 */ + r = luai_nummod(v1, v2); break; + case OP_POW: r = luai_numpow(v1, v2); break; + case OP_UNM: r = luai_numunm(v1); break; + case OP_LEN: return 0; /* no constant folding for 'len' */ + default: lua_assert(0); r = 0; break; + } + if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */ + e1->u.nval = r; + return 1; +} + + +static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { + if (constfolding(op, e1, e2)) + return; + else { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) { + freeexp(fs, e1); + freeexp(fs, e2); + } + else { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + } +} + + +static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) { + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ + cond = 1; + } + e1->u.s.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; +} + + +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { + expdesc e2; + e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; + switch (op) { + case OPR_MINUS: { + if (!isnumeral(e)) + luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */ + codearith(fs, OP_UNM, e, &e2); + break; + } + case OPR_NOT: codenot(fs, e); break; + case OPR_LEN: { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2); + break; + } + default: lua_assert(0); + } +} + + +void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { + switch (op) { + case OPR_AND: { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: + case OPR_MOD: case OPR_POW: { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: { + luaK_exp2RK(fs, v); + break; + } + } +} + + +void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { + switch (op) { + case OPR_AND: { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { + lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.s.info); + e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info; + } + else { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2); + } + break; + } + case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break; + case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break; + case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break; + case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break; + case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break; + case OPR_POW: codearith(fs, OP_POW, e1, e2); break; + case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break; + case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break; + case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break; + case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break; + case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break; + case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break; + default: lua_assert(0); + } +} + + +void luaK_fixline (FuncState *fs, int line) { + fs->f->lineinfo[fs->pc - 1] = line; +} + + +static int luaK_code (FuncState *fs, Instruction i, int line) { + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "code size overflow"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "code size overflow"); + f->lineinfo[fs->pc] = line; + return fs->pc++; +} + + +int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline); +} + + +int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline); +} + + +void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { + int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + luaK_code(fs, cast(Instruction, c), fs->ls->lastline); + } + fs->freereg = base + 1; /* free registers with list values */ +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lcode.h b/src/mod/legacy/languages/mod_lua/lua/lcode.h new file mode 100644 index 0000000000..b941c60721 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lcode.h @@ -0,0 +1,76 @@ +/* +** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums +*/ +typedef enum BinOpr { + OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, + OPR_CONCAT, + OPR_NE, OPR_EQ, + OPR_LT, OPR_LE, OPR_GT, OPR_GE, + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +#define getcode(fs,e) ((fs)->f->code[(e)->u.s.info]) + +#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/ldblib.c b/src/mod/legacy/languages/mod_lua/lua/ldblib.c new file mode 100644 index 0000000000..67de1222a9 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ldblib.c @@ -0,0 +1,397 @@ +/* +** $Id: ldblib.c,v 1.104.1.3 2008/01/21 13:11:21 roberto Exp $ +** Interface from Lua to its debug API +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldblib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static int db_getregistry (lua_State *L) { + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; +} + + +static int db_getmetatable (lua_State *L) { + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) { + lua_pushnil(L); /* no metatable */ + } + return 1; +} + + +static int db_setmetatable (lua_State *L) { + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_pushboolean(L, lua_setmetatable(L, 1)); + return 1; +} + + +static int db_getfenv (lua_State *L) { + lua_getfenv(L, 1); + return 1; +} + + +static int db_setfenv (lua_State *L) { + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + if (lua_setfenv(L, 1) == 0) + luaL_error(L, LUA_QL("setfenv") + " cannot change environment of given object"); + return 1; +} + + +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushstring(L, v); + lua_setfield(L, -2, i); +} + + +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } +} + + +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + +static int db_getinfo (lua_State *L) { + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg+1)) { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ +} + + +static int db_getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); + if (name) { + lua_xmove(L1, L, 1); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; + } +} + + +static int db_setlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); + return 1; +} + + +static int auxupvalue (lua_State *L, int get) { + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */ + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get+1)); + return get + 1; +} + + +static int db_getupvalue (lua_State *L) { + return auxupvalue(L, 1); +} + + +static int db_setupvalue (lua_State *L) { + luaL_checkany(L, 3); + return auxupvalue(L, 0); +} + + + +static const char KEY_HOOK = 'h'; + + +static void hookf (lua_State *L, lua_Debug *ar) { + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail return"}; + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } +} + + +static int makemask (const char *smask, int count) { + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; +} + + +static char *unmakemask (int mask, char *smask) { + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; +} + + +static void gethooktable (lua_State *L) { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} + + +static int db_sethook (lua_State *L) { + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + func = NULL; mask = 0; count = 0; /* turn off hooks */ + } + else { + const char *smask = luaL_checkstring(L, arg+2); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + count = luaL_optint(L, arg+3, 0); + func = hookf; mask = makemask(smask, count); + } + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_pushvalue(L, arg+1); + lua_rawset(L, -3); /* set new hook */ + lua_pop(L, 1); /* remove hook table */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; +} + + +static int db_gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else { + gethooktable(L); + lua_pushlightuserdata(L, L1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; +} + + +static int db_debug (lua_State *L) { + for (;;) { + char buffer[250]; + fputs("lua_debug> ", stderr); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) { + fputs(lua_tostring(L, -1), stderr); + fputs("\n", stderr); + } + lua_settop(L, 0); /* remove eventual returns */ + } +} + + +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ + +static int db_errorfb (lua_State *L) { + int level; + int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (lua_isnumber(L, arg+2)) { + level = (int)lua_tointeger(L, arg+2); + lua_pop(L, 1); + } + else + level = (L == L1) ? 1 : 0; /* level 0 may be this own function */ + if (lua_gettop(L) == arg) + lua_pushliteral(L, ""); + else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */ + else lua_pushliteral(L, "\n"); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) { + if (level > LEVELS1 && firstpart) { + /* no more than `LEVELS2' more levels? */ + if (!lua_getstack(L1, level+LEVELS2, &ar)) + level--; /* keep going */ + else { + lua_pushliteral(L, "\n\t..."); /* too many levels */ + while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ + level++; + } + firstpart = 0; + continue; + } + lua_pushliteral(L, "\n\t"); + lua_getinfo(L1, "Snl", &ar); + lua_pushfstring(L, "%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + if (*ar.namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, " in function " LUA_QS, ar.name); + else { + if (*ar.what == 'm') /* main? */ + lua_pushfstring(L, " in main chunk"); + else if (*ar.what == 'C' || *ar.what == 't') + lua_pushliteral(L, " ?"); /* C function or tail call */ + else + lua_pushfstring(L, " in function <%s:%d>", + ar.short_src, ar.linedefined); + } + lua_concat(L, lua_gettop(L) - arg); + } + lua_concat(L, lua_gettop(L) - arg); + return 1; +} + + +static const luaL_Reg dblib[] = { + {"debug", db_debug}, + {"getfenv", db_getfenv}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"setfenv", db_setfenv}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_errorfb}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_debug (lua_State *L) { + luaL_register(L, LUA_DBLIBNAME, dblib); + return 1; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/ldebug.c b/src/mod/legacy/languages/mod_lua/lua/ldebug.c new file mode 100644 index 0000000000..50ad3d3803 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ldebug.c @@ -0,0 +1,638 @@ +/* +** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ +** Debug Interface +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + + +#define ldebug_c +#define LUA_CORE + +#include "lua.h" + +#include "lapi.h" +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); + + +static int currentpc (lua_State *L, CallInfo *ci) { + if (!isLua(ci)) return -1; /* function is not a Lua function? */ + if (ci == L->ci) + ci->savedpc = L->savedpc; + return pcRel(ci->savedpc, ci_func(ci)->l.p); +} + + +static int currentline (lua_State *L, CallInfo *ci) { + int pc = currentpc(L, ci); + if (pc < 0) + return -1; /* only active lua functions have current-line information */ + else + return getline(ci_func(ci)->l.p, pc); +} + + +/* +** this function can be called asynchronous (e.g. during a signal) +*/ +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { + if (func == NULL || mask == 0) { /* turn off hooks? */ + mask = 0; + func = NULL; + } + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; +} + + +LUA_API lua_Hook lua_gethook (lua_State *L) { + return L->hook; +} + + +LUA_API int lua_gethookmask (lua_State *L) { + return L->hookmask; +} + + +LUA_API int lua_gethookcount (lua_State *L) { + return L->basehookcount; +} + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { + int status; + CallInfo *ci; + lua_lock(L); + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { + level--; + if (f_isLua(ci)) /* Lua function? */ + level -= ci->tailcalls; /* skip lost tail calls */ + } + if (level == 0 && ci > L->base_ci) { /* level found? */ + status = 1; + ar->i_ci = cast_int(ci - L->base_ci); + } + else if (level < 0) { /* level is of a lost tail call? */ + status = 1; + ar->i_ci = 0; + } + else status = 0; /* no such level */ + lua_unlock(L); + return status; +} + + +static Proto *getluaproto (CallInfo *ci) { + return (isLua(ci) ? ci_func(ci)->l.p : NULL); +} + + +static const char *findlocal (lua_State *L, CallInfo *ci, int n) { + const char *name; + Proto *fp = getluaproto(ci); + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) + return name; /* is a local variable in a Lua function */ + else { + StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + return "(*temporary)"; + else + return NULL; + } +} + + +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + luaA_pushobject(L, ci->base + (n - 1)); + lua_unlock(L); + return name; +} + + +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { + CallInfo *ci = L->base_ci + ar->i_ci; + const char *name = findlocal(L, ci, n); + lua_lock(L); + if (name) + setobjs2s(L, ci->base + (n - 1), L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; +} + + +static void funcinfo (lua_Debug *ar, Closure *cl) { + if (cl->c.isC) { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else { + ar->source = getstr(cl->l.p->source); + ar->linedefined = cl->l.p->linedefined; + ar->lastlinedefined = cl->l.p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +} + + +static void info_tailcall (lua_Debug *ar) { + ar->name = ar->namewhat = ""; + ar->what = "tail"; + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; + ar->source = "=(tail call)"; + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); + ar->nups = 0; +} + + +static void collectvalidlines (lua_State *L, Closure *f) { + if (f == NULL || f->c.isC) { + setnilvalue(L->top); + } + else { + Table *t = luaH_new(L, 0, 0); + int *lineinfo = f->l.p->lineinfo; + int i; + for (i=0; il.p->sizelineinfo; i++) + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); + sethvalue(L, L->top, t); + } + incr_top(L); +} + + +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) { + int status = 1; + if (f == NULL) { + info_tailcall(ar); + return status; + } + for (; *what; what++) { + switch (*what) { + case 'S': { + funcinfo(ar, f); + break; + } + case 'l': { + ar->currentline = (ci) ? currentline(L, ci) : -1; + break; + } + case 'u': { + ar->nups = f->c.nupvalues; + break; + } + case 'n': { + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; + if (ar->namewhat == NULL) { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: status = 0; /* invalid option */ + } + } + return status; +} + + +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { + int status; + Closure *f = NULL; + CallInfo *ci = NULL; + lua_lock(L); + if (*what == '>') { + StkId func = L->top - 1; + luai_apicheck(L, ttisfunction(func)); + what++; /* skip the '>' */ + f = clvalue(func); + L->top--; /* pop function */ + } + else if (ar->i_ci != 0) { /* no tail call? */ + ci = L->base_ci + ar->i_ci; + lua_assert(ttisfunction(ci->func)); + f = clvalue(ci->func); + } + status = auxgetinfo(L, what, ar, f, ci); + if (strchr(what, 'f')) { + if (f == NULL) setnilvalue(L->top); + else setclvalue(L, L->top, f); + incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, f); + lua_unlock(L); + return status; +} + + +/* +** {====================================================== +** Symbolic Execution and code checker +** ======================================================= +*/ + +#define check(x) if (!(x)) return 0; + +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) + +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) + + + +static int precheck (const Proto *pt) { + check(pt->maxstacksize <= MAXSTACK); + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); + check(!(pt->is_vararg & VARARG_NEEDSARG) || + (pt->is_vararg & VARARG_HASARG)); + check(pt->sizeupvalues <= pt->nups); + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); + return 1; +} + + +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) + +int luaG_checkopenop (Instruction i) { + switch (GET_OPCODE(i)) { + case OP_CALL: + case OP_TAILCALL: + case OP_RETURN: + case OP_SETLIST: { + check(GETARG_B(i) == 0); + return 1; + } + default: return 0; /* invalid instruction after an open call */ + } +} + + +static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { + switch (mode) { + case OpArgN: check(r == 0); break; + case OpArgU: break; + case OpArgR: checkreg(pt, r); break; + case OpArgK: + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); + break; + } + return 1; +} + + +static Instruction symbexec (const Proto *pt, int lastpc, int reg) { + int pc; + int last; /* stores position of last instruction that changed `reg' */ + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ + check(precheck(pt)); + for (pc = 0; pc < lastpc; pc++) { + Instruction i = pt->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + int b = 0; + int c = 0; + check(op < NUM_OPCODES); + checkreg(pt, a); + switch (getOpMode(op)) { + case iABC: { + b = GETARG_B(i); + c = GETARG_C(i); + check(checkArgMode(pt, b, getBMode(op))); + check(checkArgMode(pt, c, getCMode(op))); + break; + } + case iABx: { + b = GETARG_Bx(i); + if (getBMode(op) == OpArgK) check(b < pt->sizek); + break; + } + case iAsBx: { + b = GETARG_sBx(i); + if (getBMode(op) == OpArgR) { + int dest = pc+1+b; + check(0 <= dest && dest < pt->sizecode); + if (dest > 0) { + int j; + /* check that it does not jump to a setlist count; this + is tricky, because the count from a previous setlist may + have the same value of an invalid setlist; so, we must + go all the way back to the first of them (if any) */ + for (j = 0; j < dest; j++) { + Instruction d = pt->code[dest-1-j]; + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; + } + /* if 'j' is even, previous value is not a setlist (even if + it looks like one) */ + check((j&1) == 0); + } + } + break; + } + } + if (testAMode(op)) { + if (a == reg) last = pc; /* change register `a' */ + } + if (testTMode(op)) { + check(pc+2 < pt->sizecode); /* check skip */ + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); + } + switch (op) { + case OP_LOADBOOL: { + if (c == 1) { /* does it jump? */ + check(pc+2 < pt->sizecode); /* check its jump */ + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || + GETARG_C(pt->code[pc+1]) != 0); + } + break; + } + case OP_LOADNIL: { + if (a <= reg && reg <= b) + last = pc; /* set registers from `a' to `b' */ + break; + } + case OP_GETUPVAL: + case OP_SETUPVAL: { + check(b < pt->nups); + break; + } + case OP_GETGLOBAL: + case OP_SETGLOBAL: { + check(ttisstring(&pt->k[b])); + break; + } + case OP_SELF: { + checkreg(pt, a+1); + if (reg == a+1) last = pc; + break; + } + case OP_CONCAT: { + check(b < c); /* at least two operands */ + break; + } + case OP_TFORLOOP: { + check(c >= 1); /* at least one result (control variable) */ + checkreg(pt, a+2+c); /* space for results */ + if (reg >= a+2) last = pc; /* affect all regs above its base */ + break; + } + case OP_FORLOOP: + case OP_FORPREP: + checkreg(pt, a+3); + /* go through */ + case OP_JMP: { + int dest = pc+1+b; + /* not full check and jump is forward and do not skip `lastpc'? */ + if (reg != NO_REG && pc < dest && dest <= lastpc) + pc += b; /* do the jump */ + break; + } + case OP_CALL: + case OP_TAILCALL: { + if (b != 0) { + checkreg(pt, a+b-1); + } + c--; /* c = num. returns */ + if (c == LUA_MULTRET) { + check(checkopenop(pt, pc)); + } + else if (c != 0) + checkreg(pt, a+c-1); + if (reg >= a) last = pc; /* affect all registers above base */ + break; + } + case OP_RETURN: { + b--; /* b = num. returns */ + if (b > 0) checkreg(pt, a+b-1); + break; + } + case OP_SETLIST: { + if (b > 0) checkreg(pt, a + b); + if (c == 0) { + pc++; + check(pc < pt->sizecode - 1); + } + break; + } + case OP_CLOSURE: { + int nup, j; + check(b < pt->sizep); + nup = pt->p[b]->nups; + check(pc + nup < pt->sizecode); + for (j = 1; j <= nup; j++) { + OpCode op1 = GET_OPCODE(pt->code[pc + j]); + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); + } + if (reg != NO_REG) /* tracing? */ + pc += nup; /* do not 'execute' these pseudo-instructions */ + break; + } + case OP_VARARG: { + check((pt->is_vararg & VARARG_ISVARARG) && + !(pt->is_vararg & VARARG_NEEDSARG)); + b--; + if (b == LUA_MULTRET) check(checkopenop(pt, pc)); + checkreg(pt, a+b-1); + break; + } + default: break; + } + } + return pt->code[last]; +} + +#undef check +#undef checkjump +#undef checkreg + +/* }====================================================== */ + + +int luaG_checkcode (const Proto *pt) { + return (symbexec(pt, pt->sizecode, NO_REG) != 0); +} + + +static const char *kname (Proto *p, int c) { + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) + return svalue(&p->k[INDEXK(c)]); + else + return "?"; +} + + +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, + const char **name) { + if (isLua(ci)) { /* a Lua function? */ + Proto *p = ci_func(ci)->l.p; + int pc = currentpc(L, ci); + Instruction i; + *name = luaF_getlocalname(p, stackpos+1, pc); + if (*name) /* is a local? */ + return "local"; + i = symbexec(p, pc, stackpos); /* try symbolic execution */ + lua_assert(pc != -1); + switch (GET_OPCODE(i)) { + case OP_GETGLOBAL: { + int g = GETARG_Bx(i); /* global index */ + lua_assert(ttisstring(&p->k[g])); + *name = svalue(&p->k[g]); + return "global"; + } + case OP_MOVE: { + int a = GETARG_A(i); + int b = GETARG_B(i); /* move from `b' to `a' */ + if (b < a) + return getobjname(L, ci, b, name); /* get name for `b' */ + break; + } + case OP_GETTABLE: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "field"; + } + case OP_GETUPVAL: { + int u = GETARG_B(i); /* upvalue index */ + *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; + return "upvalue"; + } + case OP_SELF: { + int k = GETARG_C(i); /* key index */ + *name = kname(p, k); + return "method"; + } + default: break; + } + } + return NULL; /* no useful name found */ +} + + +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { + Instruction i; + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) + return NULL; /* calling function is not Lua (or is unknown) */ + ci--; /* calling function */ + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || + GET_OPCODE(i) == OP_TFORLOOP) + return getobjname(L, ci, GETARG_A(i), name); + else + return NULL; /* no useful name can be found */ +} + + +/* only ANSI way to check whether a pointer points to an array */ +static int isinstack (CallInfo *ci, const TValue *o) { + StkId p; + for (p = ci->base; p < ci->top; p++) + if (o == p) return 1; + return 0; +} + + +void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { + const char *name = NULL; + const char *t = luaT_typenames[ttype(o)]; + const char *kind = (isinstack(L->ci, o)) ? + getobjname(L, L->ci, cast_int(o - L->base), &name) : + NULL; + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); +} + + +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); +} + + +void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); +} + + +int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { + const char *t1 = luaT_typenames[ttype(p1)]; + const char *t2 = luaT_typenames[ttype(p2)]; + if (t1[2] == t2[2]) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); + return 0; +} + + +static void addinfo (lua_State *L, const char *msg) { + CallInfo *ci = L->ci; + if (isLua(ci)) { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(L, ci); + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } +} + + +void luaG_errormsg (lua_State *L) { + if (L->errfunc != 0) { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + incr_top(L); + luaD_call(L, L->top - 2, 1); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); +} + + +void luaG_runerror (lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/ldebug.h b/src/mod/legacy/languages/mod_lua/lua/ldebug.h new file mode 100644 index 0000000000..ba28a97248 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ldebug.h @@ -0,0 +1,33 @@ +/* +** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) + +#define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) + +#define resethookcount(L) (L->hookcount = L->basehookcount) + + +LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2); +LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_checkcode (const Proto *pt); +LUAI_FUNC int luaG_checkopenop (Instruction i); + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/ldo.c b/src/mod/legacy/languages/mod_lua/lua/ldo.c new file mode 100644 index 0000000000..8de05f728e --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ldo.c @@ -0,0 +1,518 @@ +/* +** $Id: ldo.c,v 2.38.1.3 2008/01/18 22:31:22 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define ldo_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lundump.h" +#include "lvm.h" +#include "lzio.h" + + + + +/* +** {====================================================== +** Error-recovery functions +** ======================================================= +*/ + + +/* chain list of long jump buffers */ +struct lua_longjmp { + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ +}; + + +void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { + switch (errcode) { + case LUA_ERRMEM: { + setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); + break; + } + case LUA_ERRERR: { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + case LUA_ERRSYNTAX: + case LUA_ERRRUN: { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; +} + + +static void restore_stack_limit (lua_State *L) { + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ + int inuse = cast_int(L->ci - L->base_ci); + if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ + luaD_reallocCI(L, LUAI_MAXCALLS); + } +} + + +static void resetstack (lua_State *L, int status) { + L->ci = L->base_ci; + L->base = L->ci->base; + luaF_close(L, L->base); /* close eventual pending closures */ + luaD_seterrorobj(L, status, L->base); + L->nCcalls = L->baseCcalls; + L->allowhook = 1; + restore_stack_limit(L); + L->errfunc = 0; + L->errorJmp = NULL; +} + + +void luaD_throw (lua_State *L, int errcode) { + if (L->errorJmp) { + L->errorJmp->status = errcode; + LUAI_THROW(L, L->errorJmp); + } + else { + L->status = cast_byte(errcode); + if (G(L)->panic) { + resetstack(L, errcode); + lua_unlock(L); + G(L)->panic(L); + } + exit(EXIT_FAILURE); + } +} + + +int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + struct lua_longjmp lj; + lj.status = 0; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud); + ); + L->errorJmp = lj.previous; /* restore old error handler */ + return lj.status; +} + +/* }====================================================== */ + + +static void correctstack (lua_State *L, TValue *oldstack) { + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->base_ci; ci <= L->ci; ci++) { + ci->top = (ci->top - oldstack) + L->stack; + ci->base = (ci->base - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + } + L->base = (L->base - oldstack) + L->stack; +} + + +void luaD_reallocstack (lua_State *L, int newsize) { + TValue *oldstack = L->stack; + int realsize = newsize + 1 + EXTRA_STACK; + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); + luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); + L->stacksize = realsize; + L->stack_last = L->stack+newsize; + correctstack(L, oldstack); +} + + +void luaD_reallocCI (lua_State *L, int newsize) { + CallInfo *oldci = L->base_ci; + luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); + L->size_ci = newsize; + L->ci = (L->ci - oldci) + L->base_ci; + L->end_ci = L->base_ci + L->size_ci - 1; +} + + +void luaD_growstack (lua_State *L, int n) { + if (n <= L->stacksize) /* double size is enough? */ + luaD_reallocstack(L, 2*L->stacksize); + else + luaD_reallocstack(L, L->stacksize + n); +} + + +static CallInfo *growCI (lua_State *L) { + if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ + luaD_throw(L, LUA_ERRERR); + else { + luaD_reallocCI(L, 2*L->size_ci); + if (L->size_ci > LUAI_MAXCALLS) + luaG_runerror(L, "stack overflow"); + } + return ++L->ci; +} + + +void luaD_callhook (lua_State *L, int event, int line) { + lua_Hook hook = L->hook; + if (hook && L->allowhook) { + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, L->ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + if (event == LUA_HOOKTAILRET) + ar.i_ci = 0; /* tail call; no debug information about it */ + else + ar.i_ci = cast_int(L->ci - L->base_ci); + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + L->ci->top = L->top + LUA_MINSTACK; + lua_assert(L->ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + L->ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + } +} + + +static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { + int i; + int nfixargs = p->numparams; + Table *htab = NULL; + StkId base, fixed; + for (; actual < nfixargs; ++actual) + setnilvalue(L->top++); +#if defined(LUA_COMPAT_VARARG) + if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */ + int nvar = actual - nfixargs; /* number of extra arguments */ + lua_assert(p->is_vararg & VARARG_HASARG); + luaC_checkGC(L); + htab = luaH_new(L, nvar, 1); /* create `arg' table */ + for (i=0; itop - nvar + i); + /* store counter in field `n' */ + setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar)); + } +#endif + /* move fixed parameters to final position */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i=0; itop++, fixed+i); + setnilvalue(fixed+i); + } + /* add `arg' parameter */ + if (htab) { + sethvalue(L, L->top++, htab); + lua_assert(iswhite(obj2gco(htab))); + } + return base; +} + + +static StkId tryfuncTM (lua_State *L, StkId func) { + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; +} + + + +#define inc_ci(L) \ + ((L->ci == L->end_ci) ? growCI(L) : \ + (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) + + +int luaD_precall (lua_State *L, StkId func, int nresults) { + LClosure *cl; + ptrdiff_t funcr; + if (!ttisfunction(func)) /* `func' is not a function? */ + func = tryfuncTM(L, func); /* check the `function' tag method */ + funcr = savestack(L, func); + cl = &clvalue(func)->l; + L->ci->savedpc = L->savedpc; + if (!cl->isC) { /* Lua function? prepare its call */ + CallInfo *ci; + StkId st, base; + Proto *p = cl->p; + luaD_checkstack(L, p->maxstacksize); + func = restorestack(L, funcr); + if (!p->is_vararg) { /* no varargs? */ + base = func + 1; + if (L->top > base + p->numparams) + L->top = base + p->numparams; + } + else { /* vararg function */ + int nargs = cast_int(L->top - func) - 1; + base = adjust_varargs(L, p, nargs); + func = restorestack(L, funcr); /* previous call may change the stack */ + } + ci = inc_ci(L); /* now `enter' new function */ + ci->func = func; + L->base = ci->base = base; + ci->top = L->base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + L->savedpc = p->code; /* starting point */ + ci->tailcalls = 0; + ci->nresults = nresults; + for (st = L->top; st < ci->top; st++) + setnilvalue(st); + L->top = ci->top; + if (L->hookmask & LUA_MASKCALL) { + L->savedpc++; /* hooks assume 'pc' is already incremented */ + luaD_callhook(L, LUA_HOOKCALL, -1); + L->savedpc--; /* correct 'pc' */ + } + return PCRLUA; + } + else { /* if is a C function, call it */ + CallInfo *ci; + int n; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = inc_ci(L); /* now `enter' new function */ + ci->func = restorestack(L, funcr); + L->base = ci->base = ci->func + 1; + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->nresults = nresults; + if (L->hookmask & LUA_MASKCALL) + luaD_callhook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*curr_func(L)->c.f)(L); /* do the actual call */ + lua_lock(L); + if (n < 0) /* yielding? */ + return PCRYIELD; + else { + luaD_poscall(L, L->top - n); + return PCRC; + } + } +} + + +static StkId callrethooks (lua_State *L, StkId firstResult) { + ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */ + luaD_callhook(L, LUA_HOOKRET, -1); + if (f_isLua(L->ci)) { /* Lua function? */ + while ((L->hookmask & LUA_MASKRET) && L->ci->tailcalls--) /* tail calls */ + luaD_callhook(L, LUA_HOOKTAILRET, -1); + } + return restorestack(L, fr); +} + + +int luaD_poscall (lua_State *L, StkId firstResult) { + StkId res; + int wanted, i; + CallInfo *ci; + if (L->hookmask & LUA_MASKRET) + firstResult = callrethooks(L, firstResult); + ci = L->ci--; + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->base = (ci - 1)->base; /* restore base */ + L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +} + + +/* +** Call a function (C or Lua). The function to be called is at *func. +** The arguments are on the stack, right after the function. +** When returns, all the results are on the stack, starting at the original +** function position. +*/ +void luaD_call (lua_State *L, StkId func, int nResults) { + if (++L->nCcalls >= LUAI_MAXCCALLS) { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ + luaV_execute(L, 1); /* call it */ + L->nCcalls--; + luaC_checkGC(L); +} + + +static void resume (lua_State *L, void *ud) { + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (L->status == 0) { /* start coroutine? */ + lua_assert(ci == L->base_ci && firstArg > L->base); + if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA) + return; + } + else { /* resuming from previous yield */ + lua_assert(L->status == LUA_YIELD); + L->status = 0; + if (!f_isLua(ci)) { /* `common' yield? */ + /* finish interrupted execution of `OP_CALL' */ + lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL || + GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_TAILCALL); + if (luaD_poscall(L, firstArg)) /* complete it... */ + L->top = L->ci->top; /* and correct top if not multiple results */ + } + else /* yielded inside a hook: just continue its execution */ + L->base = L->ci->base; + } + luaV_execute(L, cast_int(L->ci - L->base_ci)); +} + + +static int resume_error (lua_State *L, const char *msg) { + L->top = L->ci->base; + setsvalue2s(L, L->top, luaS_new(L, msg)); + incr_top(L); + lua_unlock(L); + return LUA_ERRRUN; +} + + +LUA_API int lua_resume (lua_State *L, int nargs) { + int status; + lua_lock(L); + if (L->status != LUA_YIELD && (L->status != 0 || L->ci != L->base_ci)) + return resume_error(L, "cannot resume non-suspended coroutine"); + if (L->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); + luai_userstateresume(L, nargs); + lua_assert(L->errfunc == 0); + L->baseCcalls = ++L->nCcalls; + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status != 0) { /* error? */ + L->status = cast_byte(status); /* mark thread as `dead' */ + luaD_seterrorobj(L, status, L->top); + L->ci->top = L->top; + } + else { + lua_assert(L->nCcalls == L->baseCcalls); + status = L->status; + } + --L->nCcalls; + lua_unlock(L); + return status; +} + + +LUA_API int lua_yield (lua_State *L, int nresults) { + luai_userstateyield(L, nresults); + lua_lock(L); + if (L->nCcalls > L->baseCcalls) + luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); + L->base = L->top - nresults; /* protect stack slots below */ + L->status = LUA_YIELD; + lua_unlock(L); + return -1; +} + + +int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) { + int status; + unsigned short oldnCcalls = L->nCcalls; + ptrdiff_t old_ci = saveci(L, L->ci); + lu_byte old_allowhooks = L->allowhook; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != 0) { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close eventual pending closures */ + luaD_seterrorobj(L, status, oldtop); + L->nCcalls = oldnCcalls; + L->ci = restoreci(L, old_ci); + L->base = L->ci->base; + L->savedpc = L->ci->savedpc; + L->allowhook = old_allowhooks; + restore_stack_limit(L); + } + L->errfunc = old_errfunc; + return status; +} + + + +/* +** Execute a protected parser. +*/ +struct SParser { /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* buffer to be used by the scanner */ + const char *name; +}; + +static void f_parser (lua_State *L, void *ud) { + int i; + Proto *tf; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = luaZ_lookahead(p->z); + luaC_checkGC(L); + tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z, + &p->buff, p->name); + cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L))); + cl->l.p = tf; + for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */ + cl->l.upvals[i] = luaF_newupval(L); + setclvalue(L, L->top, cl); + incr_top(L); +} + + +int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { + struct SParser p; + int status; + p.z = z; p.name = name; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + return status; +} + + diff --git a/src/mod/legacy/languages/mod_lua/lua/ldo.h b/src/mod/legacy/languages/mod_lua/lua/ldo.h new file mode 100644 index 0000000000..98fddac59f --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ldo.h @@ -0,0 +1,57 @@ +/* +** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 roberto Exp $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +#define luaD_checkstack(L,n) \ + if ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \ + luaD_growstack(L, n); \ + else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); + + +#define incr_top(L) {luaD_checkstack(L,1); L->top++;} + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) + +#define saveci(L,p) ((char *)(p) - (char *)L->base_ci) +#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n))) + + +/* results from luaD_precall */ +#define PCRLUA 0 /* initiated a call to a Lua function */ +#define PCRC 1 /* did a call to a C function */ +#define PCRYIELD 2 /* C funtion yielded */ + + +/* type of protected functions, to be ran by `runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); +LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize); +LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack (lua_State *L, int n); + +LUAI_FUNC void luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); + +#endif + diff --git a/src/mod/legacy/languages/mod_lua/lua/ldump.c b/src/mod/legacy/languages/mod_lua/lua/ldump.c new file mode 100644 index 0000000000..c9d3d4870f --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ldump.c @@ -0,0 +1,164 @@ +/* +** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** save precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define ldump_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lundump.h" + +typedef struct { + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; +} DumpState; + +#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) +#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) + +static void DumpBlock(const void* b, size_t size, DumpState* D) +{ + if (D->status==0) + { + lua_unlock(D->L); + D->status=(*D->writer)(D->L,b,size,D->data); + lua_lock(D->L); + } +} + +static void DumpChar(int y, DumpState* D) +{ + char x=(char)y; + DumpVar(x,D); +} + +static void DumpInt(int x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpNumber(lua_Number x, DumpState* D) +{ + DumpVar(x,D); +} + +static void DumpVector(const void* b, int n, size_t size, DumpState* D) +{ + DumpInt(n,D); + DumpMem(b,n,size,D); +} + +static void DumpString(const TString* s, DumpState* D) +{ + if (s==NULL || getstr(s)==NULL) + { + size_t size=0; + DumpVar(size,D); + } + else + { + size_t size=s->tsv.len+1; /* include trailing '\0' */ + DumpVar(size,D); + DumpBlock(getstr(s),size,D); + } +} + +#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D); + +static void DumpConstants(const Proto* f, DumpState* D) +{ + int i,n=f->sizek; + DumpInt(n,D); + for (i=0; ik[i]; + DumpChar(ttype(o),D); + switch (ttype(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o),D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o),D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o),D); + break; + default: + lua_assert(0); /* cannot happen */ + break; + } + } + n=f->sizep; + DumpInt(n,D); + for (i=0; ip[i],f->source,D); +} + +static void DumpDebug(const Proto* f, DumpState* D) +{ + int i,n; + n= (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo,n,sizeof(int),D); + n= (D->strip) ? 0 : f->sizelocvars; + DumpInt(n,D); + for (i=0; ilocvars[i].varname,D); + DumpInt(f->locvars[i].startpc,D); + DumpInt(f->locvars[i].endpc,D); + } + n= (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n,D); + for (i=0; iupvalues[i],D); +} + +static void DumpFunction(const Proto* f, const TString* p, DumpState* D) +{ + DumpString((f->source==p || D->strip) ? NULL : f->source,D); + DumpInt(f->linedefined,D); + DumpInt(f->lastlinedefined,D); + DumpChar(f->nups,D); + DumpChar(f->numparams,D); + DumpChar(f->is_vararg,D); + DumpChar(f->maxstacksize,D); + DumpCode(f,D); + DumpConstants(f,D); + DumpDebug(f,D); +} + +static void DumpHeader(DumpState* D) +{ + char h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h,LUAC_HEADERSIZE,D); +} + +/* +** dump Lua function as precompiled chunk +*/ +int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +{ + DumpState D; + D.L=L; + D.writer=w; + D.data=data; + D.strip=strip; + D.status=0; + DumpHeader(&D); + DumpFunction(f,NULL,&D); + return D.status; +} diff --git a/src/mod/legacy/languages/mod_lua/lua/lfunc.c b/src/mod/legacy/languages/mod_lua/lua/lfunc.c new file mode 100644 index 0000000000..813e88f583 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lfunc.c @@ -0,0 +1,174 @@ +/* +** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + + +#include + +#define lfunc_c +#define LUA_CORE + +#include "lua.h" + +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->c.isC = 1; + c->c.env = e; + c->c.nupvalues = cast_byte(nelems); + return c; +} + + +Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) { + Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); + luaC_link(L, obj2gco(c), LUA_TFUNCTION); + c->l.isC = 0; + c->l.env = e; + c->l.nupvalues = cast_byte(nelems); + while (nelems--) c->l.upvals[nelems] = NULL; + return c; +} + + +UpVal *luaF_newupval (lua_State *L) { + UpVal *uv = luaM_new(L, UpVal); + luaC_link(L, obj2gco(uv), LUA_TUPVAL); + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; +} + + +UpVal *luaF_findupval (lua_State *L, StkId level) { + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = ngcotouv(*pp))->v >= level) { + lua_assert(p->v != &p->u.value); + if (p->v == level) { /* found a corresponding upvalue? */ + if (isdead(g, obj2gco(p))) /* is it dead? */ + changewhite(obj2gco(p)); /* ressurect it */ + return p; + } + pp = &p->next; + } + uv = luaM_new(L, UpVal); /* not found: create a new one */ + uv->tt = LUA_TUPVAL; + uv->marked = luaC_white(g); + uv->v = level; /* current value lives in the stack */ + uv->next = *pp; /* chain it in the proper position */ + *pp = obj2gco(uv); + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; +} + + +static void unlinkupval (UpVal *uv) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; +} + + +void luaF_freeupval (lua_State *L, UpVal *uv) { + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ +} + + +void luaF_close (lua_State *L, StkId level) { + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = ngcotouv(L->openupval))->v >= level) { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else { + unlinkupval(uv); + setobj(L, &uv->u.value, uv->v); + uv->v = &uv->u.value; /* now current value lives here */ + luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ + } + } +} + + +Proto *luaF_newproto (lua_State *L) { + Proto *f = luaM_new(L, Proto); + luaC_link(L, obj2gco(f), LUA_TPROTO); + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->sizecode = 0; + f->sizelineinfo = 0; + f->sizeupvalues = 0; + f->nups = 0; + f->upvalues = NULL; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->lineinfo = NULL; + f->sizelocvars = 0; + f->locvars = NULL; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; +} + + +void luaF_freeproto (lua_State *L, Proto *f) { + luaM_freearray(L, f->code, f->sizecode, Instruction); + luaM_freearray(L, f->p, f->sizep, Proto *); + luaM_freearray(L, f->k, f->sizek, TValue); + luaM_freearray(L, f->lineinfo, f->sizelineinfo, int); + luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar); + luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *); + luaM_free(L, f); +} + + +void luaF_freeclosure (lua_State *L, Closure *c) { + int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) : + sizeLclosure(c->l.nupvalues); + luaM_freemem(L, c, size); +} + + +/* +** Look for n-th local variable at line `line' in function `func'. +** Returns NULL if not found. +*/ +const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { + int i; + for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { + if (pc < f->locvars[i].endpc) { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lfunc.h b/src/mod/legacy/languages/mod_lua/lua/lfunc.h new file mode 100644 index 0000000000..a68cf5151c --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lfunc.h @@ -0,0 +1,34 @@ +/* +** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 roberto Exp $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue)*((n)-1))) + +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *)*((n)-1))) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); +LUAI_FUNC UpVal *luaF_newupval (lua_State *L); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c); +LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lgc.c b/src/mod/legacy/languages/mod_lua/lua/lgc.c new file mode 100644 index 0000000000..d9e0b78294 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lgc.c @@ -0,0 +1,711 @@ +/* +** $Id: lgc.c,v 2.38.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#include + +#define lgc_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define GCSTEPSIZE 1024u +#define GCSWEEPMAX 40 +#define GCSWEEPCOST 10 +#define GCFINALIZECOST 100 + + +#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) + +#define makewhite(g,x) \ + ((x)->gch.marked = cast_byte(((x)->gch.marked & maskmarks) | luaC_white(g))) + +#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define black2gray(x) resetbit((x)->gch.marked, BLACKBIT) + +#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) + + +#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) +#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT) + + +#define KEYWEAK bitmask(KEYWEAKBIT) +#define VALUEWEAK bitmask(VALUEWEAKBIT) + + + +#define markvalue(g,o) { checkconsistency(o); \ + if (iscollectable(o) && iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); } + +#define markobject(g,t) { if (iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); } + + +#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) + + +static void removeentry (Node *n) { + lua_assert(ttisnil(gval(n))); + if (iscollectable(gkey(n))) + setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */ +} + + +static void reallymarkobject (global_State *g, GCObject *o) { + lua_assert(iswhite(o) && !isdead(g, o)); + white2gray(o); + switch (o->gch.tt) { + case LUA_TSTRING: { + return; + } + case LUA_TUSERDATA: { + Table *mt = gco2u(o)->metatable; + gray2black(o); /* udata are never gray */ + if (mt) markobject(g, mt); + markobject(g, gco2u(o)->env); + return; + } + case LUA_TUPVAL: { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v == &uv->u.value) /* closed? */ + gray2black(o); /* open upvalues are never black */ + return; + } + case LUA_TFUNCTION: { + gco2cl(o)->c.gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTABLE: { + gco2h(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TTHREAD: { + gco2th(o)->gclist = g->gray; + g->gray = o; + break; + } + case LUA_TPROTO: { + gco2p(o)->gclist = g->gray; + g->gray = o; + break; + } + default: lua_assert(0); + } +} + + +static void marktmu (global_State *g) { + GCObject *u = g->tmudata; + if (u) { + do { + u = u->gch.next; + makewhite(g, u); /* may be marked, if left from previous GC */ + reallymarkobject(g, u); + } while (u != g->tmudata); + } +} + + +/* move `dead' udata that need finalization to list `tmudata' */ +size_t luaC_separateudata (lua_State *L, int all) { + global_State *g = G(L); + size_t deadmem = 0; + GCObject **p = &g->mainthread->next; + GCObject *curr; + while ((curr = *p) != NULL) { + if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) + p = &curr->gch.next; /* don't bother with them */ + else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { + markfinalized(gco2u(curr)); /* don't need finalization */ + p = &curr->gch.next; + } + else { /* must call its gc method */ + deadmem += sizeudata(gco2u(curr)); + markfinalized(gco2u(curr)); + *p = curr->gch.next; + /* link `curr' at the end of `tmudata' list */ + if (g->tmudata == NULL) /* list is empty? */ + g->tmudata = curr->gch.next = curr; /* creates a circular list */ + else { + curr->gch.next = g->tmudata->gch.next; + g->tmudata->gch.next = curr; + g->tmudata = curr; + } + } + } + return deadmem; +} + + +static int traversetable (global_State *g, Table *h) { + int i; + int weakkey = 0; + int weakvalue = 0; + const TValue *mode; + if (h->metatable) + markobject(g, h->metatable); + mode = gfasttm(g, h->metatable, TM_MODE); + if (mode && ttisstring(mode)) { /* is there a weak mode? */ + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + if (weakkey || weakvalue) { /* is really weak? */ + h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ + h->marked |= cast_byte((weakkey << KEYWEAKBIT) | + (weakvalue << VALUEWEAKBIT)); + h->gclist = g->weak; /* must be cleared after GC, ... */ + g->weak = obj2gco(h); /* ... so put in the appropriate list */ + } + } + if (weakkey && weakvalue) return 1; + if (!weakvalue) { + i = h->sizearray; + while (i--) + markvalue(g, &h->array[i]); + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); + if (ttisnil(gval(n))) + removeentry(n); /* remove empty entries */ + else { + lua_assert(!ttisnil(gkey(n))); + if (!weakkey) markvalue(g, gkey(n)); + if (!weakvalue) markvalue(g, gval(n)); + } + } + return weakkey || weakvalue; +} + + +/* +** All marks are conditional because a GC may happen while the +** prototype is still being created +*/ +static void traverseproto (global_State *g, Proto *f) { + int i; + if (f->source) stringmark(f->source); + for (i=0; isizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i=0; isizeupvalues; i++) { /* mark upvalue names */ + if (f->upvalues[i]) + stringmark(f->upvalues[i]); + } + for (i=0; isizep; i++) { /* mark nested protos */ + if (f->p[i]) + markobject(g, f->p[i]); + } + for (i=0; isizelocvars; i++) { /* mark local-variable names */ + if (f->locvars[i].varname) + stringmark(f->locvars[i].varname); + } +} + + + +static void traverseclosure (global_State *g, Closure *cl) { + markobject(g, cl->c.env); + if (cl->c.isC) { + int i; + for (i=0; ic.nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->c.upvalue[i]); + } + else { + int i; + lua_assert(cl->l.nupvalues == cl->l.p->nups); + markobject(g, cl->l.p); + for (i=0; il.nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->l.upvals[i]); + } +} + + +static void checkstacksizes (lua_State *L, StkId max) { + int ci_used = cast_int(L->ci - L->base_ci); /* number of `ci' in use */ + int s_used = cast_int(max - L->stack); /* part of stack in use */ + if (L->size_ci > LUAI_MAXCALLS) /* handling overflow? */ + return; /* do not touch the stacks */ + if (4*ci_used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci) + luaD_reallocCI(L, L->size_ci/2); /* still big enough... */ + condhardstacktests(luaD_reallocCI(L, ci_used + 1)); + if (4*s_used < L->stacksize && + 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize) + luaD_reallocstack(L, L->stacksize/2); /* still big enough... */ + condhardstacktests(luaD_reallocstack(L, s_used)); +} + + +static void traversestack (global_State *g, lua_State *l) { + StkId o, lim; + CallInfo *ci; + markvalue(g, gt(l)); + lim = l->top; + for (ci = l->base_ci; ci <= l->ci; ci++) { + lua_assert(ci->top <= l->stack_last); + if (lim < ci->top) lim = ci->top; + } + for (o = l->stack; o < l->top; o++) + markvalue(g, o); + for (; o <= lim; o++) + setnilvalue(o); + checkstacksizes(l, lim); +} + + +/* +** traverse one gray object, turning it to black. +** Returns `quantity' traversed. +*/ +static l_mem propagatemark (global_State *g) { + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (o->gch.tt) { + case LUA_TTABLE: { + Table *h = gco2h(o); + g->gray = h->gclist; + if (traversetable(g, h)) /* table is weak? */ + black2gray(o); /* keep it gray */ + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * sizenode(h); + } + case LUA_TFUNCTION: { + Closure *cl = gco2cl(o); + g->gray = cl->c.gclist; + traverseclosure(g, cl); + return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : + sizeLclosure(cl->l.nupvalues); + } + case LUA_TTHREAD: { + lua_State *th = gco2th(o); + g->gray = th->gclist; + th->gclist = g->grayagain; + g->grayagain = o; + black2gray(o); + traversestack(g, th); + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * th->size_ci; + } + case LUA_TPROTO: { + Proto *p = gco2p(o); + g->gray = p->gclist; + traverseproto(g, p); + return sizeof(Proto) + sizeof(Instruction) * p->sizecode + + sizeof(Proto *) * p->sizep + + sizeof(TValue) * p->sizek + + sizeof(int) * p->sizelineinfo + + sizeof(LocVar) * p->sizelocvars + + sizeof(TString *) * p->sizeupvalues; + } + default: lua_assert(0); return 0; + } +} + + +static size_t propagateall (global_State *g) { + size_t m = 0; + while (g->gray) m += propagatemark(g); + return m; +} + + +/* +** The next function tells whether a key or value can be cleared from +** a weak table. Non-collectable objects are never removed from weak +** tables. Strings behave as `values', so are never removed too. for +** other objects: if really collected, cannot keep them; for userdata +** being finalized, keep them in keys, but not in values +*/ +static int iscleared (const TValue *o, int iskey) { + if (!iscollectable(o)) return 0; + if (ttisstring(o)) { + stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + return iswhite(gcvalue(o)) || + (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); +} + + +/* +** clear collected entries from weaktables +*/ +static void cleartable (GCObject *l) { + while (l) { + Table *h = gco2h(l); + int i = h->sizearray; + lua_assert(testbit(h->marked, VALUEWEAKBIT) || + testbit(h->marked, KEYWEAKBIT)); + if (testbit(h->marked, VALUEWEAKBIT)) { + while (i--) { + TValue *o = &h->array[i]; + if (iscleared(o, 0)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + } + i = sizenode(h); + while (i--) { + Node *n = gnode(h, i); + if (!ttisnil(gval(n)) && /* non-empty entry? */ + (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* remove entry from table */ + } + } + l = h->gclist; + } +} + + +static void freeobj (lua_State *L, GCObject *o) { + switch (o->gch.tt) { + case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; + case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; + case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TTABLE: luaH_free(L, gco2h(o)); break; + case LUA_TTHREAD: { + lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); + luaE_freethread(L, gco2th(o)); + break; + } + case LUA_TSTRING: { + G(L)->strt.nuse--; + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + case LUA_TUSERDATA: { + luaM_freemem(L, o, sizeudata(gco2u(o))); + break; + } + default: lua_assert(0); + } +} + + + +#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) + + +static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { + GCObject *curr; + global_State *g = G(L); + int deadmask = otherwhite(g); + while ((curr = *p) != NULL && count-- > 0) { + if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ + sweepwholelist(L, &gco2th(curr)->openupval); + if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ + lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); + makewhite(g, curr); /* make it white (for next cycle) */ + p = &curr->gch.next; + } + else { /* must erase `curr' */ + lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); + *p = curr->gch.next; + if (curr == g->rootgc) /* is the first element of the list? */ + g->rootgc = curr->gch.next; /* adjust first */ + freeobj(L, curr); + } + } + return p; +} + + +static void checkSizes (lua_State *L) { + global_State *g = G(L); + /* check size of string hash */ + if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && + g->strt.size > MINSTRTABSIZE*2) + luaS_resize(L, g->strt.size/2); /* table is too big */ + /* check size of buffer */ + if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ + size_t newsize = luaZ_sizebuffer(&g->buff) / 2; + luaZ_resizebuffer(L, &g->buff, newsize); + } +} + + +static void GCTM (lua_State *L) { + global_State *g = G(L); + GCObject *o = g->tmudata->gch.next; /* get first element */ + Udata *udata = rawgco2u(o); + const TValue *tm; + /* remove udata from `tmudata' */ + if (o == g->tmudata) /* last element? */ + g->tmudata = NULL; + else + g->tmudata->gch.next = udata->uv.next; + udata->uv.next = g->mainthread->next; /* return it to `root' list */ + g->mainthread->next = o; + makewhite(g, o); + tm = fasttm(L, udata->uv.metatable, TM_GC); + if (tm != NULL) { + lu_byte oldah = L->allowhook; + lu_mem oldt = g->GCthreshold; + L->allowhook = 0; /* stop debug hooks during GC tag method */ + g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ + setobj2s(L, L->top, tm); + setuvalue(L, L->top+1, udata); + L->top += 2; + luaD_call(L, L->top - 2, 0); + L->allowhook = oldah; /* restore hooks */ + g->GCthreshold = oldt; /* restore threshold */ + } +} + + +/* +** Call all GC tag methods +*/ +void luaC_callGCTM (lua_State *L) { + while (G(L)->tmudata) + GCTM(L); +} + + +void luaC_freeall (lua_State *L) { + global_State *g = G(L); + int i; + g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */ + sweepwholelist(L, &g->rootgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); +} + + +static void markmt (global_State *g) { + int i; + for (i=0; imt[i]) markobject(g, g->mt[i]); +} + + +/* mark root set */ +static void markroot (lua_State *L) { + global_State *g = G(L); + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + markobject(g, g->mainthread); + /* make global table be traversed before main stack */ + markvalue(g, gt(g->mainthread)); + markvalue(g, registry(L)); + markmt(g); + g->gcstate = GCSpropagate; +} + + +static void remarkupvals (global_State *g) { + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } +} + + +static void atomic (lua_State *L) { + global_State *g = G(L); + size_t udsize; /* total size of userdata to be finalized */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + /* traverse objects cautch by write barrier and by 'remarkupvals' */ + propagateall(g); + /* remark weak tables */ + g->gray = g->weak; + g->weak = NULL; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + markmt(g); /* mark basic metatables (again) */ + propagateall(g); + /* remark gray again */ + g->gray = g->grayagain; + g->grayagain = NULL; + propagateall(g); + udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ + marktmu(g); /* mark `preserved' userdata */ + udsize += propagateall(g); /* remark, to propagate `preserveness' */ + cleartable(g->weak); /* remove collected objects from weak tables */ + /* flip current white */ + g->currentwhite = cast_byte(otherwhite(g)); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gcstate = GCSsweepstring; + g->estimate = g->totalbytes - udsize; /* first estimate */ +} + + +static l_mem singlestep (lua_State *L) { + global_State *g = G(L); + /*lua_checkmemory(L);*/ + switch (g->gcstate) { + case GCSpause: { + markroot(L); /* start a new collection */ + return 0; + } + case GCSpropagate: { + if (g->gray) + return propagatemark(g); + else { /* no more `gray' objects */ + atomic(L); /* finish mark phase */ + return 0; + } + } + case GCSsweepstring: { + lu_mem old = g->totalbytes; + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); + if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */ + g->gcstate = GCSsweep; /* end sweep-string phase */ + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPCOST; + } + case GCSsweep: { + lu_mem old = g->totalbytes; + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + if (*g->sweepgc == NULL) { /* nothing more to sweep? */ + checkSizes(L); + g->gcstate = GCSfinalize; /* end sweep phase */ + } + lua_assert(old >= g->totalbytes); + g->estimate -= old - g->totalbytes; + return GCSWEEPMAX*GCSWEEPCOST; + } + case GCSfinalize: { + if (g->tmudata) { + GCTM(L); + if (g->estimate > GCFINALIZECOST) + g->estimate -= GCFINALIZECOST; + return GCFINALIZECOST; + } + else { + g->gcstate = GCSpause; /* end collection */ + g->gcdept = 0; + return 0; + } + } + default: lua_assert(0); return 0; + } +} + + +void luaC_step (lua_State *L) { + global_State *g = G(L); + l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; + if (lim == 0) + lim = (MAX_LUMEM-1)/2; /* no limit */ + g->gcdept += g->totalbytes - g->GCthreshold; + do { + lim -= singlestep(L); + if (g->gcstate == GCSpause) + break; + } while (lim > 0); + if (g->gcstate != GCSpause) { + if (g->gcdept < GCSTEPSIZE) + g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ + else { + g->gcdept -= GCSTEPSIZE; + g->GCthreshold = g->totalbytes; + } + } + else { + lua_assert(g->totalbytes >= g->estimate); + setthreshold(g); + } +} + + +void luaC_fullgc (lua_State *L) { + global_State *g = G(L); + if (g->gcstate <= GCSpropagate) { + /* reset sweep marks to sweep all elements (returning them to white) */ + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + /* reset other collector lists */ + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->gcstate = GCSsweepstring; + } + lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); + /* finish any pending sweep phase */ + while (g->gcstate != GCSfinalize) { + lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); + singlestep(L); + } + markroot(L); + while (g->gcstate != GCSpause) { + singlestep(L); + } + setthreshold(g); +} + + +void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + lua_assert(ttype(&o->gch) != LUA_TTABLE); + /* must keep invariant? */ + if (g->gcstate == GCSpropagate) + reallymarkobject(g, v); /* restore invariant */ + else /* don't mind */ + makewhite(g, o); /* mark as white just to avoid other barriers */ +} + + +void luaC_barrierback (lua_State *L, Table *t) { + global_State *g = G(L); + GCObject *o = obj2gco(t); + lua_assert(isblack(o) && !isdead(g, o)); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + black2gray(o); /* make table gray (again) */ + t->gclist = g->grayagain; + g->grayagain = o; +} + + +void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { + global_State *g = G(L); + o->gch.next = g->rootgc; + g->rootgc = o; + o->gch.marked = luaC_white(g); + o->gch.tt = tt; +} + + +void luaC_linkupval (lua_State *L, UpVal *uv) { + global_State *g = G(L); + GCObject *o = obj2gco(uv); + o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ + g->rootgc = o; + if (isgray(o)) { + if (g->gcstate == GCSpropagate) { + gray2black(o); /* closed upvalues need barrier */ + luaC_barrier(L, uv, uv->v); + } + else { /* sweep phase: sweep it (turning it into white) */ + makewhite(g, o); + lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); + } + } +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lgc.h b/src/mod/legacy/languages/mod_lua/lua/lgc.h new file mode 100644 index 0000000000..5a8dc605b3 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lgc.h @@ -0,0 +1,110 @@ +/* +** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpause 0 +#define GCSpropagate 1 +#define GCSsweepstring 2 +#define GCSsweep 3 +#define GCSfinalize 4 + + +/* +** some userful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) +#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2))) +#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2))) +#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2))) + + + +/* +** Layout for bit use in `marked' field: +** bit 0 - object is white (type 0) +** bit 1 - object is white (type 1) +** bit 2 - object is black +** bit 3 - for userdata: has been finalized +** bit 3 - for tables: has weak keys +** bit 4 - for tables: has weak values +** bit 5 - object is fixed (should not be collected) +** bit 6 - object is "super" fixed (only the main thread) +*/ + + +#define WHITE0BIT 0 +#define WHITE1BIT 1 +#define BLACKBIT 2 +#define FINALIZEDBIT 3 +#define KEYWEAKBIT 3 +#define VALUEWEAKBIT 4 +#define FIXEDBIT 5 +#define SFIXEDBIT 6 +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) (!isblack(x) && !iswhite(x)) + +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) + +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) + +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) + +#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) + + +#define luaC_checkGC(L) { \ + condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ + if (G(L)->totalbytes >= G(L)->GCthreshold) \ + luaC_step(L); } + + +#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),gcvalue(v)); } + +#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \ + luaC_barrierback(L,t); } + +#define luaC_objbarrier(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrierf(L,obj2gco(p),obj2gco(o)); } + +#define luaC_objbarriert(L,t,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } + +LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); +LUAI_FUNC void luaC_callGCTM (lua_State *L); +LUAI_FUNC void luaC_freeall (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_fullgc (lua_State *L); +LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); +LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); +LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/linit.c b/src/mod/legacy/languages/mod_lua/lua/linit.c new file mode 100644 index 0000000000..c1f90dfab7 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/linit.c @@ -0,0 +1,38 @@ +/* +** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ +** Initialization of libraries for lua.c +** See Copyright Notice in lua.h +*/ + + +#define linit_c +#define LUA_LIB + +#include "lua.h" + +#include "lualib.h" +#include "lauxlib.h" + + +static const luaL_Reg lualibs[] = { + {"", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL} +}; + + +LUALIB_API void luaL_openlibs (lua_State *L) { + const luaL_Reg *lib = lualibs; + for (; lib->func; lib++) { + lua_pushcfunction(L, lib->func); + lua_pushstring(L, lib->name); + lua_call(L, 1, 0); + } +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/liolib.c b/src/mod/legacy/languages/mod_lua/lua/liolib.c new file mode 100644 index 0000000000..e79ed1cb2e --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/liolib.c @@ -0,0 +1,553 @@ +/* +** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $ +** Standard I/O (and system) library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define liolib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +#define IO_INPUT 1 +#define IO_OUTPUT 2 + + +static const char *const fnames[] = {"input", "output"}; + + +static int pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + if (filename) + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + else + lua_pushfstring(L, "%s", strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static void fileerror (lua_State *L, int arg, const char *filename) { + lua_pushfstring(L, "%s: %s", filename, strerror(errno)); + luaL_argerror(L, arg, lua_tostring(L, -1)); +} + + +#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE)) + + +static int io_type (lua_State *L) { + void *ud; + luaL_checkany(L, 1); + ud = lua_touserdata(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); + if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) + lua_pushnil(L); /* not a file */ + else if (*((FILE **)ud) == NULL) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; +} + + +static FILE *tofile (lua_State *L) { + FILE **f = tofilep(L); + if (*f == NULL) + luaL_error(L, "attempt to use a closed file"); + return *f; +} + + + +/* +** When creating file handles, always creates a `closed' file handle +** before opening the actual file; so, if there is a memory error, the +** file is not left opened. +*/ +static FILE **newfile (lua_State *L) { + FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); + *pf = NULL; /* file handle is currently `closed' */ + luaL_getmetatable(L, LUA_FILEHANDLE); + lua_setmetatable(L, -2); + return pf; +} + + +/* +** function to (not) close the standard files stdin, stdout, and stderr +*/ +static int io_noclose (lua_State *L) { + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; +} + + +/* +** function to close 'popen' files +*/ +static int io_pclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = lua_pclose(L, *p); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +/* +** function to close regular files +*/ +static int io_fclose (lua_State *L) { + FILE **p = tofilep(L); + int ok = (fclose(*p) == 0); + *p = NULL; + return pushresult(L, ok, NULL); +} + + +static int aux_close (lua_State *L) { + lua_getfenv(L, 1); + lua_getfield(L, -1, "__close"); + return (lua_tocfunction(L, -1))(L); +} + + +static int io_close (lua_State *L) { + if (lua_isnone(L, 1)) + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); + tofile(L); /* make sure argument is a file */ + return aux_close(L); +} + + +static int io_gc (lua_State *L) { + FILE *f = *tofilep(L); + /* ignore closed files */ + if (f != NULL) + aux_close(L); + return 0; +} + + +static int io_tostring (lua_State *L) { + FILE *f = *tofilep(L); + if (f == NULL) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", f); + return 1; +} + + +static int io_open (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +/* +** this function has a separated environment, which defines the +** correct __close for 'popen' files +*/ +static int io_popen (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + FILE **pf = newfile(L); + *pf = lua_popen(L, filename, mode); + return (*pf == NULL) ? pushresult(L, 0, filename) : 1; +} + + +static int io_tmpfile (lua_State *L) { + FILE **pf = newfile(L); + *pf = tmpfile(); + return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; +} + + +static FILE *getiofile (lua_State *L, int findex) { + FILE *f; + lua_rawgeti(L, LUA_ENVIRONINDEX, findex); + f = *(FILE **)lua_touserdata(L, -1); + if (f == NULL) + luaL_error(L, "standard %s file is closed", fnames[findex - 1]); + return f; +} + + +static int g_iofile (lua_State *L, int f, const char *mode) { + if (!lua_isnoneornil(L, 1)) { + const char *filename = lua_tostring(L, 1); + if (filename) { + FILE **pf = newfile(L); + *pf = fopen(filename, mode); + if (*pf == NULL) + fileerror(L, 1, filename); + } + else { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_rawseti(L, LUA_ENVIRONINDEX, f); + } + /* return current value */ + lua_rawgeti(L, LUA_ENVIRONINDEX, f); + return 1; +} + + +static int io_input (lua_State *L) { + return g_iofile(L, IO_INPUT, "r"); +} + + +static int io_output (lua_State *L) { + return g_iofile(L, IO_OUTPUT, "w"); +} + + +static int io_readline (lua_State *L); + + +static void aux_lines (lua_State *L, int idx, int toclose) { + lua_pushvalue(L, idx); + lua_pushboolean(L, toclose); /* close/not close file when finished */ + lua_pushcclosure(L, io_readline, 2); +} + + +static int f_lines (lua_State *L) { + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 1, 0); + return 1; +} + + +static int io_lines (lua_State *L) { + if (lua_isnoneornil(L, 1)) { /* no arguments? */ + /* will iterate over default input */ + lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); + return f_lines(L); + } + else { + const char *filename = luaL_checkstring(L, 1); + FILE **pf = newfile(L); + *pf = fopen(filename, "r"); + if (*pf == NULL) + fileerror(L, 1, filename); + aux_lines(L, lua_gettop(L), 1); + return 1; + } +} + + +/* +** {====================================================== +** READ +** ======================================================= +*/ + + +static int read_number (lua_State *L, FILE *f) { + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { + lua_pushnumber(L, d); + return 1; + } + else return 0; /* read fails */ +} + + +static int test_eof (lua_State *L, FILE *f) { + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); +} + + +static int read_line (lua_State *L, FILE *f) { + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_objlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l-1] != '\n') + luaL_addsize(&b, l); + else { + luaL_addsize(&b, l - 1); /* do not include `eol' */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } +} + + +static int read_chars (lua_State *L, FILE *f, size_t n) { + size_t rlen; /* how much to read */ + size_t nr; /* number of chars actually read */ + luaL_Buffer b; + luaL_buffinit(L, &b); + rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ + do { + char *p = luaL_prepbuffer(&b); + if (rlen > n) rlen = n; /* cannot read more than asked */ + nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + n -= nr; /* still have to read `n' chars */ + } while (n > 0 && nr == rlen); /* until end of count or eof */ + luaL_pushresult(&b); /* close buffer */ + return (n == 0 || lua_objlen(L, -1) > 0); +} + + +static int g_read (lua_State *L, FILE *f, int first) { + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) { /* no arguments? */ + success = read_line(L, f); + n = first+1; /* to return 1 result */ + } + else { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) { + if (lua_type(L, n) == LUA_TNUMBER) { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f); + break; + case 'a': /* file */ + read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return pushresult(L, 0, NULL); + if (!success) { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; +} + + +static int io_read (lua_State *L) { + return g_read(L, getiofile(L, IO_INPUT), 1); +} + + +static int f_read (lua_State *L) { + return g_read(L, tofile(L), 2); +} + + +static int io_readline (lua_State *L) { + FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); + int sucess; + if (f == NULL) /* file is already closed? */ + luaL_error(L, "file is already closed"); + sucess = read_line(L, f); + if (ferror(f)) + return luaL_error(L, "%s", strerror(errno)); + if (sucess) return 1; + else { /* EOF */ + if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } +} + +/* }====================================================== */ + + +static int g_write (lua_State *L, FILE *f, int arg) { + int nargs = lua_gettop(L) - 1; + int status = 1; + for (; nargs--; arg++) { + if (lua_type(L, arg) == LUA_TNUMBER) { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + return pushresult(L, status, NULL); +} + + +static int io_write (lua_State *L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +} + + +static int f_write (lua_State *L) { + return g_write(L, tofile(L), 2); +} + + +static int f_seek (lua_State *L) { + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + long offset = luaL_optlong(L, 3, 0); + op = fseek(f, offset, mode[op]); + if (op) + return pushresult(L, 0, NULL); /* error */ + else { + lua_pushinteger(L, ftell(f)); + return 1; + } +} + + +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], sz); + return pushresult(L, res == 0, NULL); +} + + + +static int io_flush (lua_State *L) { + return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +} + + +static int f_flush (lua_State *L) { + return pushresult(L, fflush(tofile(L)) == 0, NULL); +} + + +static const luaL_Reg iolib[] = { + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL} +}; + + +static const luaL_Reg flib[] = { + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", io_gc}, + {"__tostring", io_tostring}, + {NULL, NULL} +}; + + +static void createmeta (lua_State *L) { + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_register(L, NULL, flib); /* file methods */ +} + + +static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { + *newfile(L) = f; + if (k > 0) { + lua_pushvalue(L, -1); + lua_rawseti(L, LUA_ENVIRONINDEX, k); + } + lua_pushvalue(L, -2); /* copy environment */ + lua_setfenv(L, -2); /* set it */ + lua_setfield(L, -3, fname); +} + + +static void newfenv (lua_State *L, lua_CFunction cls) { + lua_createtable(L, 0, 1); + lua_pushcfunction(L, cls); + lua_setfield(L, -2, "__close"); +} + + +LUALIB_API int luaopen_io (lua_State *L) { + createmeta(L); + /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ + newfenv(L, io_fclose); + lua_replace(L, LUA_ENVIRONINDEX); + /* open library */ + luaL_register(L, LUA_IOLIBNAME, iolib); + /* create (and set) default files */ + newfenv(L, io_noclose); /* close function for default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, 0, "stderr"); + lua_pop(L, 1); /* pop environment for default files */ + lua_getfield(L, -1, "popen"); + newfenv(L, io_pclose); /* create environment for 'popen' */ + lua_setfenv(L, -2); /* set fenv for 'popen' */ + lua_pop(L, 1); /* pop 'popen' */ + return 1; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/llex.c b/src/mod/legacy/languages/mod_lua/lua/llex.c new file mode 100644 index 0000000000..6dc319358c --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/llex.c @@ -0,0 +1,461 @@ +/* +** $Id: llex.c,v 2.20.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define llex_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "llex.h" +#include "lobject.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "lzio.h" + + + +#define next(ls) (ls->current = zgetc(ls->z)) + + + + +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') + + +/* ORDER RESERVED */ +const char *const luaX_tokens [] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", + "", "", "", "", + NULL +}; + + +#define save_and_next(ls) (save(ls, ls->current), next(ls)) + + +static void save (LexState *ls, int c) { + Mbuffer *b = ls->buff; + if (b->n + 1 > b->buffsize) { + size_t newsize; + if (b->buffsize >= MAX_SIZET/2) + luaX_lexerror(ls, "lexical element too long", 0); + newsize = b->buffsize * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[b->n++] = cast(char, c); +} + + +void luaX_init (lua_State *L) { + int i; + for (i=0; itsv.reserved = cast_byte(i+1); /* reserved word */ + } +} + + +#define MAXSRC 80 + + +const char *luaX_token2str (LexState *ls, int token) { + if (token < FIRST_RESERVED) { + lua_assert(token == cast(unsigned char, token)); + return (iscntrl(token)) ? luaO_pushfstring(ls->L, "char(%d)", token) : + luaO_pushfstring(ls->L, "%c", token); + } + else + return luaX_tokens[token-FIRST_RESERVED]; +} + + +static const char *txtToken (LexState *ls, int token) { + switch (token) { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaZ_buffer(ls->buff); + default: + return luaX_token2str(ls, token); + } +} + + +void luaX_lexerror (LexState *ls, const char *msg, int token) { + char buff[MAXSRC]; + luaO_chunkid(buff, getstr(ls->source), MAXSRC); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near " LUA_QS, msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); +} + + +void luaX_syntaxerror (LexState *ls, const char *msg) { + luaX_lexerror(ls, msg, ls->t.token); +} + + +TString *luaX_newstring (LexState *ls, const char *str, size_t l) { + lua_State *L = ls->L; + TString *ts = luaS_newlstr(L, str, l); + TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */ + if (ttisnil(o)) + setbvalue(o, 1); /* make sure `str' will not be collected */ + return ts; +} + + +static void inclinenumber (LexState *ls) { + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); +} + + +void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { + ls->decpoint = '.'; + ls->L = L; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ + next(ls); /* read first char */ +} + + + +/* +** ======================================================= +** LEXICAL ANALYZER +** ======================================================= +*/ + + + +static int check_next (LexState *ls, const char *set) { + if (!strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; +} + + +static void buffreplace (LexState *ls, char from, char to) { + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; +} + + +static void trydecpoint (LexState *ls, SemInfo *seminfo) { + /* format error: try to update decimal point separator */ + struct lconv *cv = localeconv(); + char old = ls->decpoint; + ls->decpoint = (cv ? cv->decimal_point[0] : '.'); + buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + luaX_lexerror(ls, "malformed number", TK_NUMBER); + } +} + + +/* LUA_NUMBER */ +static void read_numeral (LexState *ls, SemInfo *seminfo) { + lua_assert(isdigit(ls->current)); + do { + save_and_next(ls); + } while (isdigit(ls->current) || ls->current == '.'); + if (check_next(ls, "Ee")) /* `E'? */ + check_next(ls, "+-"); /* optional exponent sign */ + while (isalnum(ls->current) || ls->current == '_') + save_and_next(ls); + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ +} + + +static int skip_sep (LexState *ls) { + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; +} + + +static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { + int cont = 0; + (void)(cont); /* avoid warnings when `cont' is not used */ + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, (seminfo) ? "unfinished long string" : + "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ +#if defined(LUA_COMPAT_LSTR) + case '[': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `[' */ + cont++; +#if LUA_COMPAT_LSTR == 1 + if (sep == 0) + luaX_lexerror(ls, "nesting of [[...]] is deprecated", '['); +#endif + } + break; + } +#endif + case ']': { + if (skip_sep(ls) == sep) { + save_and_next(ls); /* skip 2nd `]' */ +#if defined(LUA_COMPAT_LSTR) && LUA_COMPAT_LSTR == 2 + cont--; + if (sep == 0 && cont >= 0) break; +#endif + goto endloop; + } + break; + } + case '\n': + case '\r': { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: { + if (seminfo) save_and_next(ls); + else next(ls); + } + } + } endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2*(2 + sep)); +} + + +static void read_string (LexState *ls, int del, SemInfo *seminfo) { + save_and_next(ls); + while (ls->current != del) { + switch (ls->current) { + case EOZ: + luaX_lexerror(ls, "unfinished string", TK_EOS); + continue; /* to avoid warnings */ + case '\n': + case '\r': + luaX_lexerror(ls, "unfinished string", TK_STRING); + continue; /* to avoid warnings */ + case '\\': { + int c; + next(ls); /* do not save the `\' */ + switch (ls->current) { + case 'a': c = '\a'; break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + case '\n': /* go through */ + case '\r': save(ls, '\n'); inclinenumber(ls); continue; + case EOZ: continue; /* will raise an error next loop */ + default: { + if (!isdigit(ls->current)) + save_and_next(ls); /* handles \\, \", \', and \? */ + else { /* \xxx */ + int i = 0; + c = 0; + do { + c = 10*c + (ls->current-'0'); + next(ls); + } while (++i<3 && isdigit(ls->current)); + if (c > UCHAR_MAX) + luaX_lexerror(ls, "escape sequence too large", TK_STRING); + save(ls, c); + } + continue; + } + } + save(ls, c); + next(ls); + continue; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); +} + + +static int llex (LexState *ls, SemInfo *seminfo) { + luaZ_resetbuffer(ls->buff); + for (;;) { + switch (ls->current) { + case '\n': + case '\r': { + inclinenumber(ls); + continue; + } + case '-': { + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') { + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) { + read_long_string(ls, NULL, sep); /* long comment */ + luaZ_resetbuffer(ls->buff); + continue; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); + continue; + } + case '[': { + int sep = skip_sep(ls); + if (sep >= 0) { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) return '['; + else luaX_lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': { + next(ls); + if (ls->current != '=') return '='; + else { next(ls); return TK_EQ; } + } + case '<': { + next(ls); + if (ls->current != '=') return '<'; + else { next(ls); return TK_LE; } + } + case '>': { + next(ls); + if (ls->current != '=') return '>'; + else { next(ls); return TK_GE; } + } + case '~': { + next(ls); + if (ls->current != '=') return '~'; + else { next(ls); return TK_NE; } + } + case '"': + case '\'': { + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': { + save_and_next(ls); + if (check_next(ls, ".")) { + if (check_next(ls, ".")) + return TK_DOTS; /* ... */ + else return TK_CONCAT; /* .. */ + } + else if (!isdigit(ls->current)) return '.'; + else { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + } + case EOZ: { + return TK_EOS; + } + default: { + if (isspace(ls->current)) { + lua_assert(!currIsNewline(ls)); + next(ls); + continue; + } + else if (isdigit(ls->current)) { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + else if (isalpha(ls->current) || ls->current == '_') { + /* identifier or reserved word */ + TString *ts; + do { + save_and_next(ls); + } while (isalnum(ls->current) || ls->current == '_'); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + if (ts->tsv.reserved > 0) /* reserved word? */ + return ts->tsv.reserved - 1 + FIRST_RESERVED; + else { + seminfo->ts = ts; + return TK_NAME; + } + } + else { + int c = ls->current; + next(ls); + return c; /* single-char tokens (+ - / ...) */ + } + } + } + } +} + + +void luaX_next (LexState *ls) { + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +} + + +void luaX_lookahead (LexState *ls) { + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/llex.h b/src/mod/legacy/languages/mod_lua/lua/llex.h new file mode 100644 index 0000000000..a9201cee48 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/llex.h @@ -0,0 +1,81 @@ +/* +** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include "lobject.h" +#include "lzio.h" + + +#define FIRST_RESERVED 257 + +/* maximum length of a reserved word */ +#define TOKEN_LEN (sizeof("function")/sizeof(char)) + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER, + TK_NAME, TK_STRING, TK_EOS +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) + + +/* array with token `names' */ +LUAI_DATA const char *const luaX_tokens []; + + +typedef union { + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* `FuncState' is private to the parser */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + TString *source; /* current source name */ + char decpoint; /* locale decimal point */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC void luaX_lookahead (LexState *ls); +LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token); +LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/llimits.h b/src/mod/legacy/languages/mod_lua/lua/llimits.h new file mode 100644 index 0000000000..ca8dcb7224 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/llimits.h @@ -0,0 +1,128 @@ +/* +** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 roberto Exp $ +** Limits, basic types, and some other `installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +typedef LUAI_UINT32 lu_int32; + +typedef LUAI_UMEM lu_mem; + +typedef LUAI_MEM l_mem; + + + +/* chars used as small naturals (so that `char' is reserved for characters) */ +typedef unsigned char lu_byte; + + +#define MAX_SIZET ((size_t)(~(size_t)0)-2) + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) + + +#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ + +/* +** conversion of pointer to integer +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) + + + +/* type to ensure maximum alignment */ +typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; + + +/* result of a `usual argument conversion' over lua_Number */ +typedef LUAI_UACNUMBER l_uacNumber; + + +/* internal assertions for in-house debugging */ +#ifdef lua_assert + +#define check_exp(c,e) (lua_assert(c), (e)) +#define api_check(l,e) lua_assert(e) + +#else + +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define api_check luai_apicheck + +#endif + + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#endif + + +#ifndef cast +#define cast(t, exp) ((t)(exp)) +#endif + +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) + + + +/* +** type for virtual-machine instructions +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +typedef lu_int32 Instruction; + + + +/* maximum stack for a Lua function */ +#define MAXSTACK 250 + + + +/* minimum size for the string table (must be power of 2) */ +#ifndef MINSTRTABSIZE +#define MINSTRTABSIZE 32 +#endif + + +/* minimum size for string buffer */ +#ifndef LUA_MINBUFFER +#define LUA_MINBUFFER 32 +#endif + + +#ifndef lua_lock +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +#ifndef luai_threadyield +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#ifndef HARDSTACKTESTS +#define condhardstacktests(x) ((void)0) +#else +#define condhardstacktests(x) x +#endif + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lmathlib.c b/src/mod/legacy/languages/mod_lua/lua/lmathlib.c new file mode 100644 index 0000000000..441fbf736c --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lmathlib.c @@ -0,0 +1,263 @@ +/* +** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 roberto Exp $ +** Standard mathematical library +** See Copyright Notice in lua.h +*/ + + +#include +#include + +#define lmathlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#undef PI +#define PI (3.14159265358979323846) +#define RADIANS_PER_DEGREE (PI/180.0) + + + +static int math_abs (lua_State *L) { + lua_pushnumber(L, fabs(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sin (lua_State *L) { + lua_pushnumber(L, sin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_sinh (lua_State *L) { + lua_pushnumber(L, sinh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cos (lua_State *L) { + lua_pushnumber(L, cos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_cosh (lua_State *L) { + lua_pushnumber(L, cosh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tan (lua_State *L) { + lua_pushnumber(L, tan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_tanh (lua_State *L) { + lua_pushnumber(L, tanh(luaL_checknumber(L, 1))); + return 1; +} + +static int math_asin (lua_State *L) { + lua_pushnumber(L, asin(luaL_checknumber(L, 1))); + return 1; +} + +static int math_acos (lua_State *L) { + lua_pushnumber(L, acos(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan (lua_State *L) { + lua_pushnumber(L, atan(luaL_checknumber(L, 1))); + return 1; +} + +static int math_atan2 (lua_State *L) { + lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_ceil (lua_State *L) { + lua_pushnumber(L, ceil(luaL_checknumber(L, 1))); + return 1; +} + +static int math_floor (lua_State *L) { + lua_pushnumber(L, floor(luaL_checknumber(L, 1))); + return 1; +} + +static int math_fmod (lua_State *L) { + lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_modf (lua_State *L) { + double ip; + double fp = modf(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; +} + +static int math_sqrt (lua_State *L) { + lua_pushnumber(L, sqrt(luaL_checknumber(L, 1))); + return 1; +} + +static int math_pow (lua_State *L) { + lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2))); + return 1; +} + +static int math_log (lua_State *L) { + lua_pushnumber(L, log(luaL_checknumber(L, 1))); + return 1; +} + +static int math_log10 (lua_State *L) { + lua_pushnumber(L, log10(luaL_checknumber(L, 1))); + return 1; +} + +static int math_exp (lua_State *L) { + lua_pushnumber(L, exp(luaL_checknumber(L, 1))); + return 1; +} + +static int math_deg (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); + return 1; +} + +static int math_rad (lua_State *L) { + lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); + return 1; +} + +static int math_frexp (lua_State *L) { + int e; + lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; +} + +static int math_ldexp (lua_State *L) { + lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2))); + return 1; +} + + + +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; +} + + +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i=2; i<=n; i++) { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; +} + + +static int math_random (lua_State *L) { + /* the `%' avoids the (rare) case of r==1, and is needed also because on + some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ + lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: { /* only upper limit */ + int u = luaL_checkint(L, 1); + luaL_argcheck(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ + break; + } + case 2: { /* lower and upper limits */ + int l = luaL_checkint(L, 1); + int u = luaL_checkint(L, 2); + luaL_argcheck(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ + break; + } + default: return luaL_error(L, "wrong number of arguments"); + } + return 1; +} + + +static int math_randomseed (lua_State *L) { + srand(luaL_checkint(L, 1)); + return 0; +} + + +static const luaL_Reg mathlib[] = { + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, + {"log10", math_log10}, + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {NULL, NULL} +}; + + +/* +** Open math library +*/ +LUALIB_API int luaopen_math (lua_State *L) { + luaL_register(L, LUA_MATHLIBNAME, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); +#if defined(LUA_COMPAT_MOD) + lua_getfield(L, -1, "fmod"); + lua_setfield(L, -2, "mod"); +#endif + return 1; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lmem.c b/src/mod/legacy/languages/mod_lua/lua/lmem.c new file mode 100644 index 0000000000..ae7d8c965f --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lmem.c @@ -0,0 +1,86 @@ +/* +** $Id: lmem.c,v 1.70.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + + +#include + +#define lmem_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" + + + +/* +** About the realloc function: +** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); +** (`osize' is the old size, `nsize' is the new size) +** +** Lua ensures that (ptr == NULL) iff (osize == 0). +** +** * frealloc(ud, NULL, 0, x) creates a new block of size `x' +** +** * frealloc(ud, p, x, 0) frees the block `p' +** (in this specific case, frealloc must return NULL). +** particularly, frealloc(ud, NULL, 0, 0) does nothing +** (which is equivalent to free(NULL) in ANSI C) +** +** frealloc returns NULL if it cannot create or reallocate the area +** (any reallocation to an equal or smaller size cannot fail!) +*/ + + + +#define MINSIZEARRAY 4 + + +void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *errormsg) { + void *newblock; + int newsize; + if (*size >= limit/2) { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, errormsg); + newsize = limit; /* still have at least one free place */ + } + else { + newsize = (*size)*2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; +} + + +void *luaM_toobig (lua_State *L) { + luaG_runerror(L, "memory allocation error: block too big"); + return NULL; /* to avoid warnings */ +} + + + +/* +** generic allocation routine. +*/ +void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + global_State *g = G(L); + lua_assert((osize == 0) == (block == NULL)); + block = (*g->frealloc)(g->ud, block, osize, nsize); + if (block == NULL && nsize > 0) + luaD_throw(L, LUA_ERRMEM); + lua_assert((nsize == 0) == (block == NULL)); + g->totalbytes = (g->totalbytes - osize) + nsize; + return block; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lmem.h b/src/mod/legacy/languages/mod_lua/lua/lmem.h new file mode 100644 index 0000000000..7c2dcb3220 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lmem.h @@ -0,0 +1,49 @@ +/* +** $Id: lmem.h,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + +#define MEMERRMSG "not enough memory" + + +#define luaM_reallocv(L,b,on,n,e) \ + ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ + luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ + luaM_toobig(L)) + +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) + +#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) +#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L,n,t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if ((nelems)+1 > (size)) \ + ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) + + +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_toobig (lua_State *L); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *errormsg); + +#endif + diff --git a/src/mod/legacy/languages/mod_lua/lua/loadlib.c b/src/mod/legacy/languages/mod_lua/lua/loadlib.c new file mode 100644 index 0000000000..0589b61fed --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/loadlib.c @@ -0,0 +1,666 @@ +/* +** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ +** Dynamic library loader for Lua +** See Copyright Notice in lua.h +** +** This module contains an implementation of loadlib for Unix systems +** that have dlfcn, an implementation for Darwin (Mac OS X), an +** implementation for Windows, and a stub for other systems. +*/ + + +#include +#include + + +#define loadlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* prefix for open functions in C libraries */ +#define LUA_POF "luaopen_" + +/* separator for open functions in C libraries */ +#define LUA_OFSEP "_" + + +#define LIBPREFIX "LOADLIB: " + +#define POF LUA_POF +#define LIB_FAIL "open" + + +/* error codes for ll_loadfunc */ +#define ERRLIB 1 +#define ERRFUNC 2 + +#define setprogdir(L) ((void)0) + + +static void ll_unloadlib (void *lib); +static void *ll_load (lua_State *L, const char *path); +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); + + + +#if defined(LUA_DL_DLOPEN) +/* +** {======================================================================== +** This is an implementation of loadlib based on the dlfcn interface. +** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, +** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least +** as an emulation layer on top of native functions. +** ========================================================================= +*/ + +#include + +static void ll_unloadlib (void *lib) { + dlclose(lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + void *lib = dlopen(path, RTLD_NOW); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DLL) +/* +** {====================================================================== +** This is an implementation of loadlib for Windows using native functions. +** ======================================================================= +*/ + +#include + + +#undef setprogdir + +static void setprogdir (lua_State *L) { + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff)/sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); + lua_remove(L, -2); /* remove original string */ + } +} + + +static void pusherror (lua_State *L) { + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); +} + +static void ll_unloadlib (void *lib) { + FreeLibrary((HINSTANCE)lib); +} + + +static void *ll_load (lua_State *L, const char *path) { + HINSTANCE lib = LoadLibraryA(path); + if (lib == NULL) pusherror(L); + return lib; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); + if (f == NULL) pusherror(L); + return f; +} + +/* }====================================================== */ + + + +#elif defined(LUA_DL_DYLD) +/* +** {====================================================================== +** Native Mac OS X / Darwin Implementation +** ======================================================================= +*/ + +#include + + +/* Mac appends a `_' before C function names */ +#undef POF +#define POF "_" LUA_POF + + +static void pusherror (lua_State *L) { + const char *err_str; + const char *err_file; + NSLinkEditErrors err; + int err_num; + NSLinkEditError(&err, &err_num, &err_file, &err_str); + lua_pushstring(L, err_str); +} + + +static const char *errorfromcode (NSObjectFileImageReturnCode ret) { + switch (ret) { + case NSObjectFileImageInappropriateFile: + return "file is not a bundle"; + case NSObjectFileImageArch: + return "library is for wrong CPU type"; + case NSObjectFileImageFormat: + return "bad format"; + case NSObjectFileImageAccess: + return "cannot access file"; + case NSObjectFileImageFailure: + default: + return "unable to load library"; + } +} + + +static void ll_unloadlib (void *lib) { + NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); +} + + +static void *ll_load (lua_State *L, const char *path) { + NSObjectFileImage img; + NSObjectFileImageReturnCode ret; + /* this would be a rare case, but prevents crashing if it happens */ + if (!_dyld_present()) { + lua_pushliteral(L, "dyld not present"); + return NULL; + } + ret = NSCreateObjectFileImageFromFile(path, &img); + if (ret == NSObjectFileImageSuccess) { + NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | + NSLINKMODULE_OPTION_RETURN_ON_ERROR); + NSDestroyObjectFileImage(img); + if (mod == NULL) pusherror(L); + return mod; + } + lua_pushstring(L, errorfromcode(ret)); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); + if (nss == NULL) { + lua_pushfstring(L, "symbol " LUA_QS " not found", sym); + return NULL; + } + return (lua_CFunction)NSAddressOfSymbol(nss); +} + +/* }====================================================== */ + + + +#else +/* +** {====================================================== +** Fallback for other systems +** ======================================================= +*/ + +#undef LIB_FAIL +#define LIB_FAIL "absent" + + +#define DLMSG "dynamic libraries not enabled; check your Lua installation" + + +static void ll_unloadlib (void *lib) { + (void)lib; /* to avoid warnings */ +} + + +static void *ll_load (lua_State *L, const char *path) { + (void)path; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + + +static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { + (void)lib; (void)sym; /* to avoid warnings */ + lua_pushliteral(L, DLMSG); + return NULL; +} + +/* }====================================================== */ +#endif + + + +static void **ll_register (lua_State *L, const char *path) { + void **plib; + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ + if (!lua_isnil(L, -1)) /* is there an entry? */ + plib = (void **)lua_touserdata(L, -1); + else { /* no entry yet; create one */ + lua_pop(L, 1); + plib = (void **)lua_newuserdata(L, sizeof(const void *)); + *plib = NULL; + luaL_getmetatable(L, "_LOADLIB"); + lua_setmetatable(L, -2); + lua_pushfstring(L, "%s%s", LIBPREFIX, path); + lua_pushvalue(L, -2); + lua_settable(L, LUA_REGISTRYINDEX); + } + return plib; +} + + +/* +** __gc tag method: calls library's `ll_unloadlib' function with the lib +** handle +*/ +static int gctm (lua_State *L) { + void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); + if (*lib) ll_unloadlib(*lib); + *lib = NULL; /* mark library as closed */ + return 0; +} + + +static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { + void **reg = ll_register(L, path); + if (*reg == NULL) *reg = ll_load(L, path); + if (*reg == NULL) + return ERRLIB; /* unable to load library */ + else { + lua_CFunction f = ll_sym(L, *reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); + return 0; /* return function */ + } +} + + +static int ll_loadlib (lua_State *L) { + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } +} + + + +/* +** {====================================================== +** 'require' function +** ======================================================= +*/ + + +static int readable (const char *filename) { + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; +} + + +static const char *pushnexttemplate (lua_State *L, const char *path) { + const char *l; + while (*path == *LUA_PATHSEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATHSEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; +} + + +static const char *findfile (lua_State *L, const char *name, + const char *pname) { + const char *path; + name = luaL_gsub(L, name, ".", LUA_DIRSEP); + lua_getfield(L, LUA_ENVIRONINDEX, pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + lua_pushliteral(L, ""); /* error accumulator */ + while ((path = pushnexttemplate(L, path)) != NULL) { + const char *filename; + filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + lua_concat(L, 2); /* add entry to possible error message */ + } + return NULL; /* not found */ +} + + +static void loaderror (lua_State *L, const char *filename) { + luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); +} + + +static int loader_Lua (lua_State *L) { + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path"); + if (filename == NULL) return 1; /* library not found in this path */ + if (luaL_loadfile(L, filename) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static const char *mkfuncname (lua_State *L, const char *modname) { + const char *funcname; + const char *mark = strchr(modname, *LUA_IGMARK); + if (mark) modname = mark + 1; + funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); + funcname = lua_pushfstring(L, POF"%s", funcname); + lua_remove(L, -2); /* remove 'gsub' result */ + return funcname; +} + + +static int loader_C (lua_State *L) { + const char *funcname; + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath"); + if (filename == NULL) return 1; /* library not found in this path */ + funcname = mkfuncname(L, name); + if (ll_loadfunc(L, filename, funcname) != 0) + loaderror(L, filename); + return 1; /* library loaded successfully */ +} + + +static int loader_Croot (lua_State *L) { + const char *funcname; + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath"); + if (filename == NULL) return 1; /* root not found */ + funcname = mkfuncname(L, name); + if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { + if (stat != ERRFUNC) loaderror(L, filename); /* real error */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; /* function not found */ + } + return 1; +} + + +static int loader_preload (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_ENVIRONINDEX, "preload"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.preload") " must be a table"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; +} + + +static const int sentinel_ = 0; +#define sentinel ((void *)&sentinel_) + + +static int ll_require (lua_State *L) { + const char *name = luaL_checkstring(L, 1); + int i; + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); + if (lua_toboolean(L, -1)) { /* is it there? */ + if (lua_touserdata(L, -1) == sentinel) /* check loops */ + luaL_error(L, "loop or previous error loading module " LUA_QS, name); + return 1; /* package is already loaded */ + } + /* else must load it; iterate over available loaders */ + lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); + if (!lua_istable(L, -1)) + luaL_error(L, LUA_QL("package.loaders") " must be a table"); + lua_pushliteral(L, ""); /* error message accumulator */ + for (i=1; ; i++) { + lua_rawgeti(L, -2, i); /* get a loader */ + if (lua_isnil(L, -1)) + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -2)); + lua_pushstring(L, name); + lua_call(L, 1, 1); /* call it */ + if (lua_isfunction(L, -1)) /* did it find module? */ + break; /* module loaded successfully */ + else if (lua_isstring(L, -1)) /* loader returned error message? */ + lua_concat(L, 2); /* accumulate it */ + else + lua_pop(L, 1); + } + lua_pushlightuserdata(L, sentinel); + lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ + lua_pushstring(L, name); /* pass name as argument to module */ + lua_call(L, 1, 1); /* run loaded module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; +} + +/* }====================================================== */ + + + +/* +** {====================================================== +** 'module' function +** ======================================================= +*/ + + +static void setfenv (lua_State *L) { + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); + lua_setfenv(L, -2); + lua_pop(L, 1); +} + + +static void dooptions (lua_State *L, int n) { + int i; + for (i = 2; i <= n; i++) { + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } +} + + +static void modinit (lua_State *L, const char *modname) { + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) dot = modname; + else dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); +} + + +static int ll_module (lua_State *L) { + const char *modname = luaL_checkstring(L, 1); + int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) + return luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ + } + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + setfenv(L); + dooptions(L, loaded - 1); + return 0; +} + + +static int ll_seeall (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushvalue(L, LUA_GLOBALSINDEX); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; +} + + +/* }====================================================== */ + + + +/* auxiliary mark (for internal use) */ +#define AUXMARK "\1" + +static void setpath (lua_State *L, const char *fieldname, const char *envname, + const char *def) { + const char *path = getenv(envname); + if (path == NULL) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, + LUA_PATHSEP AUXMARK LUA_PATHSEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); +} + + +static const luaL_Reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {"seeall", ll_seeall}, + {NULL, NULL} +}; + + +static const luaL_Reg ll_funcs[] = { + {"module", ll_module}, + {"require", ll_require}, + {NULL, NULL} +}; + + +static const lua_CFunction loaders[] = + {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; + + +LUALIB_API int luaopen_package (lua_State *L) { + int i; + /* create new type _LOADLIB */ + luaL_newmetatable(L, "_LOADLIB"); + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); + /* create `package' table */ + luaL_register(L, LUA_LOADLIBNAME, pk_funcs); +#if defined(LUA_COMPAT_LOADLIB) + lua_getfield(L, -1, "loadlib"); + lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); +#endif + lua_pushvalue(L, -1); + lua_replace(L, LUA_ENVIRONINDEX); + /* create `loaders' table */ + lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); + /* fill it with pre-defined loaders */ + for (i=0; loaders[i] != NULL; i++) { + lua_pushcfunction(L, loaders[i]); + lua_rawseti(L, -2, i+1); + } + lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ + setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ + setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" + LUA_EXECDIR "\n" LUA_IGMARK); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + lua_newtable(L); + lua_setfield(L, -2, "preload"); + lua_pushvalue(L, LUA_GLOBALSINDEX); + luaL_register(L, NULL, ll_funcs); /* open lib into global table */ + lua_pop(L, 1); + return 1; /* return 'package' table */ +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lobject.c b/src/mod/legacy/languages/mod_lua/lua/lobject.c new file mode 100644 index 0000000000..4ff50732a4 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lobject.c @@ -0,0 +1,214 @@ +/* +** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $ +** Some generic functions over Lua objects +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include +#include + +#define lobject_c +#define LUA_CORE + +#include "lua.h" + +#include "ldo.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "lvm.h" + + + +const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; + + +/* +** converts an integer to a "floating point byte", represented as +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. +*/ +int luaO_int2fb (unsigned int x) { + int e = 0; /* expoent */ + while (x >= 16) { + x = (x+1) >> 1; + e++; + } + if (x < 8) return x; + else return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 31; + if (e == 0) return x; + else return ((x & 7)+8) << (e - 1); +} + + +int luaO_log2 (unsigned int x) { + static const lu_byte log_2[256] = { + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + }; + int l = -1; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; + +} + + +int luaO_rawequalObj (const TValue *t1, const TValue *t2) { + if (ttype(t1) != ttype(t2)) return 0; + else switch (ttype(t1)) { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } +} + + +int luaO_str2d (const char *s, lua_Number *result) { + char *endptr; + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* conversion failed */ + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ + *result = cast_num(strtoul(s, &endptr, 16)); + if (*endptr == '\0') return 1; /* most common case */ + while (isspace(cast(unsigned char, *endptr))) endptr++; + if (*endptr != '\0') return 0; /* invalid trailing characters? */ + return 1; +} + + + +static void pushstr (lua_State *L, const char *str) { + setsvalue2s(L, L->top, luaS_new(L, str)); + incr_top(L); +} + + +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ +const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { + int n = 1; + pushstr(L, ""); + for (;;) { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); + incr_top(L); + switch (*(e+1)) { + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s); + break; + } + case 'c': { + char buff[2]; + buff[0] = cast(char, va_arg(argp, int)); + buff[1] = '\0'; + pushstr(L, buff); + break; + } + case 'd': { + setnvalue(L->top, cast_num(va_arg(argp, int))); + incr_top(L); + break; + } + case 'f': { + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); + incr_top(L); + break; + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff); + break; + } + case '%': { + pushstr(L, "%"); + break; + } + default: { + char buff[3]; + buff[0] = '%'; + buff[1] = *(e+1); + buff[2] = '\0'; + pushstr(L, buff); + break; + } + } + n += 2; + fmt = e+2; + } + pushstr(L, fmt); + luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); + L->top -= n; + return svalue(L->top - 1); +} + + +const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; +} + + +void luaO_chunkid (char *out, const char *source, size_t bufflen) { + if (*source == '=') { + strncpy(out, source+1, bufflen); /* remove first char */ + out[bufflen-1] = '\0'; /* ensures null termination */ + } + else { /* out = "source", or "...source" */ + if (*source == '@') { + size_t l; + source++; /* skip the `@' */ + bufflen -= sizeof(" '...' "); + l = strlen(source); + strcpy(out, ""); + if (l > bufflen) { + source += (l-bufflen); /* get last part of file name */ + strcat(out, "..."); + } + strcat(out, source); + } + else { /* out = [string "string"] */ + size_t len = strcspn(source, "\n\r"); /* stop at first newline */ + bufflen -= sizeof(" [string \"...\"] "); + if (len > bufflen) len = bufflen; + strcpy(out, "[string \""); + if (source[len] != '\0') { /* must truncate? */ + strncat(out, source, len); + strcat(out, "..."); + } + else + strcat(out, source); + strcat(out, "\"]"); + } + } +} diff --git a/src/mod/legacy/languages/mod_lua/lua/lobject.h b/src/mod/legacy/languages/mod_lua/lua/lobject.h new file mode 100644 index 0000000000..f1e447ef3b --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lobject.h @@ -0,0 +1,381 @@ +/* +** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* tags for values visible from Lua */ +#define LAST_TAG LUA_TTHREAD + +#define NUM_TAGS (LAST_TAG+1) + + +/* +** Extra tags for non-values +*/ +#define LUA_TPROTO (LAST_TAG+1) +#define LUA_TUPVAL (LAST_TAG+2) +#define LUA_TDEADKEY (LAST_TAG+3) + + +/* +** Union of all collectable objects +*/ +typedef union GCObject GCObject; + + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked + + +/* +** Common header in struct form +*/ +typedef struct GCheader { + CommonHeader; +} GCheader; + + + + +/* +** Union of all Lua values +*/ +typedef union { + GCObject *gc; + void *p; + lua_Number n; + int b; +} Value; + + +/* +** Tagged Values +*/ + +#define TValuefields Value value; int tt + +typedef struct lua_TValue { + TValuefields; +} TValue; + + +/* Macros to test type */ +#define ttisnil(o) (ttype(o) == LUA_TNIL) +#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) +#define ttisstring(o) (ttype(o) == LUA_TSTRING) +#define ttistable(o) (ttype(o) == LUA_TTABLE) +#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) +#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) +#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) +#define ttisthread(o) (ttype(o) == LUA_TTHREAD) +#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) + +/* Macros to access values */ +#define ttype(o) ((o)->tt) +#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) +#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) +#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n) +#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl) +#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h) +#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b) +#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th) + +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) + +/* +** for internal debug only +*/ +#define checkconsistency(obj) \ + lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) + +#define checkliveness(g,obj) \ + lua_assert(!iscollectable(obj) || \ + ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) + + +/* Macros to set values */ +#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) + +#define setnvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } + +#define setpvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } + +#define setbvalue(obj,x) \ + { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } + +#define setsvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ + checkliveness(G(L),i_o); } + +#define setuvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ + checkliveness(G(L),i_o); } + +#define setthvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ + checkliveness(G(L),i_o); } + +#define setclvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ + checkliveness(G(L),i_o); } + +#define sethvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ + checkliveness(G(L),i_o); } + +#define setptvalue(L,obj,x) \ + { TValue *i_o=(obj); \ + i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ + checkliveness(G(L),i_o); } + + + + +#define setobj(L,obj1,obj2) \ + { const TValue *o2=(obj2); TValue *o1=(obj1); \ + o1->value = o2->value; o1->tt=o2->tt; \ + checkliveness(G(L),o1); } + + +/* +** different types of sets, according to destination +*/ + +/* from stack to (same) stack */ +#define setobjs2s setobj +/* to stack (not from same stack) */ +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue +/* from table to same table */ +#define setobjt2t setobj +/* to table */ +#define setobj2t setobj +/* to new object */ +#define setobj2n setobj +#define setsvalue2n setsvalue + +#define setttype(obj, tt) (ttype(obj) = (tt)) + + +#define iscollectable(o) (ttype(o) >= LUA_TSTRING) + + + +typedef TValue *StkId; /* index to stack elements */ + + +/* +** String headers for string table +*/ +typedef union TString { + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct { + CommonHeader; + lu_byte reserved; + unsigned int hash; + size_t len; + } tsv; +} TString; + + +#define getstr(ts) cast(const char *, (ts) + 1) +#define svalue(o) getstr(rawtsvalue(o)) + + + +typedef union Udata { + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; + } uv; +} Udata; + + + + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines */ + struct LocVar *locvars; /* information about local variables */ + TString **upvalues; /* upvalue names */ + TString *source; + int sizeupvalues; + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte nups; /* number of upvalues */ + lu_byte numparams; + lu_byte is_vararg; + lu_byte maxstacksize; +} Proto; + + +/* masks for new-style vararg */ +#define VARARG_HASARG 1 +#define VARARG_ISVARARG 2 +#define VARARG_NEEDSARG 4 + + +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + + +/* +** Upvalues +*/ + +typedef struct UpVal { + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; +} UpVal; + + +/* +** Closures +*/ + +#define ClosureHeader \ + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ + struct Table *env + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC) +#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC) + + +/* +** Tables +*/ + +typedef union TKey { + struct { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

lsizenode)) + + +#define luaO_nilobject (&luaO_nilobject_) + +LUAI_DATA const TValue luaO_nilobject_; + +#define ceillog2(x) (luaO_log2((x)-1) + 1) + +LUAI_FUNC int luaO_log2 (unsigned int x); +LUAI_FUNC int luaO_int2fb (unsigned int x); +LUAI_FUNC int luaO_fb2int (int x); +LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); +LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); + + +#endif + diff --git a/src/mod/legacy/languages/mod_lua/lua/lopcodes.c b/src/mod/legacy/languages/mod_lua/lua/lopcodes.c new file mode 100644 index 0000000000..4cc745230b --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lopcodes.c @@ -0,0 +1,102 @@ +/* +** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** See Copyright Notice in lua.h +*/ + + +#define lopcodes_c +#define LUA_CORE + + +#include "lopcodes.h" + + +/* ORDER OP */ + +const char *const luaP_opnames[NUM_OPCODES+1] = { + "MOVE", + "LOADK", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETGLOBAL", + "GETTABLE", + "SETGLOBAL", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "POW", + "UNM", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORLOOP", + "SETLIST", + "CLOSE", + "CLOSURE", + "VARARG", + NULL +}; + + +#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) + +const lu_byte luaP_opmodes[NUM_OPCODES] = { +/* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ + ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ + ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ + ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ +}; + diff --git a/src/mod/legacy/languages/mod_lua/lua/lopcodes.h b/src/mod/legacy/languages/mod_lua/lua/lopcodes.h new file mode 100644 index 0000000000..41224d6ee1 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lopcodes.h @@ -0,0 +1,268 @@ +/* +** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned numbers. + All instructions have an opcode in the first 6 bits. + Instructions can have the following fields: + `A' : 8 bits + `B' : 9 bits + `C' : 9 bits + `Bx' : 18 bits (`B' and `C' together) + `sBx' : signed Bx + + A signed argument is represented in excess K; that is, the number + value is the unsigned value minus K. K is exactly the maximum value + for that argument (so that -max is represented by 0, and +max is + represented by 2*max), which is half the maximum for the corresponding + unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 + +#define SIZE_OP 6 + +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C + + +/* +** limits for opcode arguments. +** we use (signed) int to manipulate most arguments, +** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) +*/ +#if SIZE_Bx < LUAI_BITSINT-1 +#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#else +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT +#endif + + +#define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0))) +#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \ + ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0))) +#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \ + ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0))) +#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \ + ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0))) +#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \ + ((cast(Instruction, b)< C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + +OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ +OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + +OP_FORLOOP,/* A sBx R(A)+=R(A+2); + if R(A) =) R(A)*/ +OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ + +OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ +} OpCode; + + +#define NUM_OPCODES (cast(int, OP_VARARG) + 1) + + + +/*=========================================================================== + Notes: + (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1, + and can be 0: OP_CALL then sets `top' to last_result+1, so + next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'. + + (*) In OP_VARARG, if (B == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + + (*) In OP_RETURN, if (B == 0) then return up to `top' + + (*) In OP_SETLIST, if (B == 0) then B = `top'; + if (C == 0) then next `instruction' is real C + + (*) For comparisons, A specifies what condition the test should accept + (true or false). + + (*) All `skips' (pc++) assume that next instruction is a jump +===========================================================================*/ + + +/* +** masks for instruction properties. The format is: +** bits 0-1: op mode +** bits 2-3: C arg mode +** bits 4-5: B arg mode +** bit 6: instruction set register A +** bit 7: operator is a test +*/ + +enum OpArgMask { + OpArgN, /* argument is not used */ + OpArgU, /* argument is used */ + OpArgR, /* argument is a register or a jump offset */ + OpArgK /* argument is a constant or register/constant */ +}; + +LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES]; + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) + + +LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/loslib.c b/src/mod/legacy/languages/mod_lua/lua/loslib.c new file mode 100644 index 0000000000..da06a572ac --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/loslib.c @@ -0,0 +1,243 @@ +/* +** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $ +** Standard Operating System library +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define loslib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +static int os_pushresult (lua_State *L, int i, const char *filename) { + int en = errno; /* calls to Lua API may change this value */ + if (i) { + lua_pushboolean(L, 1); + return 1; + } + else { + lua_pushnil(L); + lua_pushfstring(L, "%s: %s", filename, strerror(en)); + lua_pushinteger(L, en); + return 3; + } +} + + +static int os_execute (lua_State *L) { + lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); + return 1; +} + + +static int os_remove (lua_State *L) { + const char *filename = luaL_checkstring(L, 1); + return os_pushresult(L, remove(filename) == 0, filename); +} + + +static int os_rename (lua_State *L) { + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return os_pushresult(L, rename(fromname, toname) == 0, fromname); +} + + +static int os_tmpname (lua_State *L) { + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; +} + + +static int os_getenv (lua_State *L) { + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; +} + + +static int os_clock (lua_State *L) { + lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); + return 1; +} + + +/* +** {====================================================== +** Time/Date operations +** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S, +** wday=%w+1, yday=%j, isdst=? } +** ======================================================= +*/ + +static void setfield (lua_State *L, const char *key, int value) { + lua_pushinteger(L, value); + lua_setfield(L, -2, key); +} + +static void setboolfield (lua_State *L, const char *key, int value) { + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); +} + +static int getboolfield (lua_State *L, const char *key) { + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; +} + + +static int getfield (lua_State *L, const char *key, int d) { + int res; + lua_getfield(L, -1, key); + if (lua_isnumber(L, -1)) + res = (int)lua_tointeger(L, -1); + else { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; +} + + +static int os_date (lua_State *L) { + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm *stm; + if (*s == '!') { /* UTC? */ + stm = gmtime(&t); + s++; /* skip `!' */ + } + else + stm = localtime(&t); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon+1); + setfield(L, "year", stm->tm_year+1900); + setfield(L, "wday", stm->tm_wday+1); + setfield(L, "yday", stm->tm_yday+1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else { + char cc[3]; + luaL_Buffer b; + cc[0] = '%'; cc[2] = '\0'; + luaL_buffinit(L, &b); + for (; *s; s++) { + if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */ + luaL_addchar(&b, *s); + else { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + cc[1] = *(++s); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; +} + + +static int os_time (lua_State *L) { + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; +} + + +static int os_difftime (lua_State *L) { + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; +} + +/* }====================================================== */ + + +static int os_setlocale (lua_State *L) { + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; +} + + +static int os_exit (lua_State *L) { + exit(luaL_optint(L, 1, EXIT_SUCCESS)); +} + +static const luaL_Reg syslib[] = { + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL} +}; + +/* }====================================================== */ + + + +LUALIB_API int luaopen_os (lua_State *L) { + luaL_register(L, LUA_OSLIBNAME, syslib); + return 1; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lparser.c b/src/mod/legacy/languages/mod_lua/lua/lparser.c new file mode 100644 index 0000000000..1e2a9a88b7 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lparser.c @@ -0,0 +1,1339 @@ +/* +** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + + +#include + +#define lparser_c +#define LUA_CORE + +#include "lua.h" + +#include "lcode.h" +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "llex.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" + + + +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) + +#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]]) + +#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m) + + +/* +** nodes for block list (list of active blocks) +*/ +typedef struct BlockCnt { + struct BlockCnt *previous; /* chain */ + int breaklist; /* list of jumps out of this loop */ + lu_byte nactvar; /* # active locals outside the breakable structure */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isbreakable; /* true if `block' is a loop */ +} BlockCnt; + + + +/* +** prototypes for recursive non-terminal functions +*/ +static void chunk (LexState *ls); +static void expr (LexState *ls, expdesc *v); + + +static void anchor_token (LexState *ls) { + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } +} + + +static void error_expected (LexState *ls, int token) { + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token))); +} + + +static void errorlimit (FuncState *fs, int limit, const char *what) { + const char *msg = (fs->f->linedefined == 0) ? + luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : + luaO_pushfstring(fs->L, "function at line %d has more than %d %s", + fs->f->linedefined, limit, what); + luaX_lexerror(fs->ls, msg, 0); +} + + +static int testnext (LexState *ls, int c) { + if (ls->t.token == c) { + luaX_next(ls); + return 1; + } + else return 0; +} + + +static void check (LexState *ls, int c) { + if (ls->t.token != c) + error_expected(ls, c); +} + +static void checknext (LexState *ls, int c) { + check(ls, c); + luaX_next(ls); +} + + +#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } + + + +static void check_match (LexState *ls, int what, int who, int where) { + if (!testnext(ls, what)) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + LUA_QS " expected (to close " LUA_QS " at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } +} + + +static TString *str_checkname (LexState *ls) { + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; +} + + +static void init_exp (expdesc *e, expkind k, int i) { + e->f = e->t = NO_JUMP; + e->k = k; + e->u.s.info = i; +} + + +static void codestring (LexState *ls, expdesc *e, TString *s) { + init_exp(e, VK, luaK_stringK(ls->fs, s)); +} + + +static void checkname(LexState *ls, expdesc *e) { + codestring(ls, e, str_checkname(ls)); +} + + +static int registerlocalvar (LexState *ls, TString *varname) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "too many local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; +} + + +#define new_localvarliteral(ls,v,n) \ + new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n) + + +static void new_localvar (LexState *ls, TString *name, int n) { + FuncState *fs = ls->fs; + luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables"); + fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name)); +} + + +static void adjustlocalvars (LexState *ls, int nvars) { + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) { + getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc; + } +} + + +static void removevars (LexState *ls, int tolevel) { + FuncState *fs = ls->fs; + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar).endpc = fs->pc; +} + + +static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { + int i; + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + for (i=0; inups; i++) { + if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) { + lua_assert(f->upvalues[i] == name); + return i; + } + } + /* new one */ + luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues"); + luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, + TString *, MAX_INT, ""); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; + f->upvalues[f->nups] = name; + luaC_objbarrier(fs->L, f, name); + lua_assert(v->k == VLOCAL || v->k == VUPVAL); + fs->upvalues[f->nups].k = cast_byte(v->k); + fs->upvalues[f->nups].info = cast_byte(v->u.s.info); + return f->nups++; +} + + +static int searchvar (FuncState *fs, TString *n) { + int i; + for (i=fs->nactvar-1; i >= 0; i--) { + if (n == getlocvar(fs, i).varname) + return i; + } + return -1; /* not found */ +} + + +static void markupval (FuncState *fs, int level) { + BlockCnt *bl = fs->bl; + while (bl && bl->nactvar > level) bl = bl->previous; + if (bl) bl->upval = 1; +} + + +static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { + if (fs == NULL) { /* no more levels? */ + init_exp(var, VGLOBAL, NO_REG); /* default is global variable */ + return VGLOBAL; + } + else { + int v = searchvar(fs, n); /* look up at current level */ + if (v >= 0) { + init_exp(var, VLOCAL, v); + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else { /* not found at current level; try upper one */ + if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) + return VGLOBAL; + var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ + var->k = VUPVAL; /* upvalue in this level */ + return VUPVAL; + } + } +} + + +static void singlevar (LexState *ls, expdesc *var) { + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VGLOBAL) + var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ +} + + +static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra-1); + } + else { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } +} + + +static void enterlevel (LexState *ls) { + if (++ls->L->nCcalls > LUAI_MAXCCALLS) + luaX_lexerror(ls, "chunk has too many syntax levels", 0); +} + + +#define leavelevel(ls) ((ls)->L->nCcalls--) + + +static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { + bl->breaklist = NO_JUMP; + bl->isbreakable = isbreakable; + bl->nactvar = fs->nactvar; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); +} + + +static void leaveblock (FuncState *fs) { + BlockCnt *bl = fs->bl; + fs->bl = bl->previous; + removevars(fs->ls, bl->nactvar); + if (bl->upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + /* a block either controls scope or breaks (never both) */ + lua_assert(!bl->isbreakable || !bl->upval); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + luaK_patchtohere(fs, bl->breaklist); +} + + +static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizep; + int i; + luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, + MAXARG_Bx, "constant table overflow"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + f->p[fs->np++] = func->f; + luaC_objbarrier(ls->L, f, func->f); + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); + for (i=0; if->nups; i++) { + OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0); + } +} + + +static void open_func (LexState *ls, FuncState *fs) { + lua_State *L = ls->L; + Proto *f = luaF_newproto(L); + fs->f = f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + fs->L = L; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = -1; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->bl = NULL; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L, 0, 0); + /* anchor table of constants and prototype (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + setptvalue2s(L, L->top, f); + incr_top(L); +} + + +static void close_func (LexState *ls) { + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + removevars(ls, 0); + luaK_ret(fs, 0, 0); /* final return */ + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *); + f->sizeupvalues = f->nups; + lua_assert(luaG_checkcode(f)); + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + L->top -= 2; /* remove table and prototype from the stack */ + /* last token read was anchored in defunct function; must reanchor it */ + if (fs) anchor_token(ls); +} + + +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) { + struct LexState lexstate; + struct FuncState funcstate; + lexstate.buff = buff; + luaX_setinput(L, &lexstate, z, luaS_new(L, name)); + open_func(&lexstate, &funcstate); + funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */ + luaX_next(&lexstate); /* read first token */ + chunk(&lexstate); + check(&lexstate, TK_EOS); + close_func(&lexstate); + lua_assert(funcstate.prev == NULL); + lua_assert(funcstate.f->nups == 0); + lua_assert(lexstate.fs == NULL); + return funcstate.f; +} + + + +/*============================================================*/ +/* GRAMMAR RULES */ +/*============================================================*/ + + +static void field (LexState *ls, expdesc *v) { + /* field -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyreg(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); +} + + +static void yindex (LexState *ls, expdesc *v) { + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); +} + + +/* +** {====================================================================== +** Rules for Constructors +** ======================================================================= +*/ + + +struct ConsControl { + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ +}; + + +static void recfield (LexState *ls, struct ConsControl *cc) { + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) { + luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ +} + + +static void closelistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) { + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } +} + + +static void lastlistfield (FuncState *fs, struct ConsControl *cc) { + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); + } +} + + +static void listfield (LexState *ls, struct ConsControl *cc) { + expr(ls, &cc->v); + luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; +} + + +static void constructor (LexState *ls, expdesc *t) { + /* constructor -> ?? */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ + checknext(ls, '{'); + do { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + switch(ls->t.token) { + case TK_NAME: { /* may be listfields or recfields */ + luaX_lookahead(ls); + if (ls->lookahead.token != '=') /* expression? */ + listfield(ls, &cc); + else + recfield(ls, &cc); + break; + } + case '[': { /* constructor_item -> recfield */ + recfield(ls, &cc); + break; + } + default: { /* constructor_part -> listfield */ + listfield(ls, &cc); + break; + } + } + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ +} + +/* }====================================================================== */ + + + +static void parlist (LexState *ls) { + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') { /* is `parlist' not empty? */ + do { + switch (ls->t.token) { + case TK_NAME: { /* param -> NAME */ + new_localvar(ls, str_checkname(ls), nparams++); + break; + } + case TK_DOTS: { /* param -> `...' */ + luaX_next(ls); +#if defined(LUA_COMPAT_VARARG) + /* use `arg' as default name */ + new_localvarliteral(ls, "arg", nparams++); + f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG; +#endif + f->is_vararg |= VARARG_ISVARARG; + break; + } + default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG)); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +} + + +static void body (LexState *ls, expdesc *e, int needself, int line) { + /* body -> `(' parlist `)' chunk END */ + FuncState new_fs; + open_func(ls, &new_fs); + new_fs.f->linedefined = line; + checknext(ls, '('); + if (needself) { + new_localvarliteral(ls, "self", 0); + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + chunk(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + close_func(ls); + pushclosure(ls, &new_fs, e); +} + + +static int explist1 (LexState *ls, expdesc *v) { + /* explist1 -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; +} + + +static void funcargs (LexState *ls, expdesc *f) { + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + int line = ls->linenumber; + switch (ls->t.token) { + case '(': { /* funcargs -> `(' [ explist1 ] `)' */ + if (line != ls->lastline) + luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else { + explist1(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: { + luaX_syntaxerror(ls, "function arguments expected"); + return; + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.s.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base+1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); + luaK_fixline(fs, line); + fs->freereg = base+1; /* call remove function and arguments and leaves + (unless changed) one result */ +} + + + + +/* +** {====================================================================== +** Expression parsing +** ======================================================================= +*/ + + +static void prefixexp (LexState *ls, expdesc *v) { + /* prefixexp -> NAME | '(' expr ')' */ + switch (ls->t.token) { + case '(': { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: { + singlevar(ls, v); + return; + } + default: { + luaX_syntaxerror(ls, "unexpected symbol"); + return; + } + } +} + + +static void primaryexp (LexState *ls, expdesc *v) { + /* primaryexp -> + prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ + FuncState *fs = ls->fs; + prefixexp(ls, v); + for (;;) { + switch (ls->t.token) { + case '.': { /* field */ + field(ls, v); + break; + } + case '[': { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyreg(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v); + break; + } + case '(': case TK_STRING: case '{': { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v); + break; + } + default: return; + } + } +} + + +static void simpleexp (LexState *ls, expdesc *v) { + /* simpleexp -> NUMBER | STRING | NIL | true | false | ... | + constructor | FUNCTION body | primaryexp */ + switch (ls->t.token) { + case TK_NUMBER: { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */ + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: { + primaryexp(ls, v); + return; + } + } + luaX_next(ls); +} + + +static UnOpr getunopr (int op) { + switch (op) { + case TK_NOT: return OPR_NOT; + case '-': return OPR_MINUS; + case '#': return OPR_LEN; + default: return OPR_NOUNOPR; + } +} + + +static BinOpr getbinopr (int op) { + switch (op) { + case '+': return OPR_ADD; + case '-': return OPR_SUB; + case '*': return OPR_MUL; + case '/': return OPR_DIV; + case '%': return OPR_MOD; + case '^': return OPR_POW; + case TK_CONCAT: return OPR_CONCAT; + case TK_NE: return OPR_NE; + case TK_EQ: return OPR_EQ; + case '<': return OPR_LT; + case TK_LE: return OPR_LE; + case '>': return OPR_GT; + case TK_GE: return OPR_GE; + case TK_AND: return OPR_AND; + case TK_OR: return OPR_OR; + default: return OPR_NOBINOPR; + } +} + + +static const struct { + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { /* ORDER OPR */ + {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */ + {10, 9}, {5, 4}, /* power and concat (right associative) */ + {3, 3}, {3, 3}, /* equality and inequality */ + {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */ + {2, 2}, {1, 1} /* logical (and/or) */ +}; + +#define UNARY_PRIORITY 8 /* priority for unary operators */ + + +/* +** subexpr -> (simpleexp | unop subexpr) { binop subexpr } +** where `binop' is any binary operator with a priority higher than `limit' +*/ +static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) { + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v); + } + else simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) { + expdesc v2; + BinOpr nextop; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ +} + + +static void expr (LexState *ls, expdesc *v) { + subexpr(ls, v, 0); +} + +/* }==================================================================== */ + + + +/* +** {====================================================================== +** Rules for Statements +** ======================================================================= +*/ + + +static int block_follow (int token) { + switch (token) { + case TK_ELSE: case TK_ELSEIF: case TK_END: + case TK_UNTIL: case TK_EOS: + return 1; + default: return 0; + } +} + + +static void block (LexState *ls) { + /* block -> chunk */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + chunk(ls); + lua_assert(bl.breaklist == NO_JUMP); + leaveblock(fs); +} + + +/* +** structure to chain all variables in the left-hand side of an +** assignment +*/ +struct LHS_assign { + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ +}; + + +/* +** check whether, in an assignment to a local variable, the local variable +** is needed in a previous assignment (to a table). If so, save original +** local value in a safe place and use this safe copy in the previous +** assignment. +*/ +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) { + if (lh->v.k == VINDEXED) { + if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.info = extra; /* previous assignment will use safe copy */ + } + if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ + conflict = 1; + lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) { + luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ + luaK_reserveregs(fs, 1); + } +} + + +static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { + expdesc e; + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, + "syntax error"); + if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + primaryexp(ls, &nv.v); + if (nv.v.k == VLOCAL) + check_conflict(ls, lh, &nv.v); + luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls, + "variables in assignment"); + assignment(ls, &nv, nvars+1); + } + else { /* assignment -> `=' explist1 */ + int nexps; + checknext(ls, '='); + nexps = explist1(ls, &e); + if (nexps != nvars) { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); +} + + +static int cond (LexState *ls) { + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; +} + + +static void breakstat (LexState *ls) { + FuncState *fs = ls->fs; + BlockCnt *bl = fs->bl; + int upval = 0; + while (bl && !bl->isbreakable) { + upval |= bl->upval; + bl = bl->previous; + } + if (!bl) + luaX_syntaxerror(ls, "no loop to break"); + if (upval) + luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); + luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); +} + + +static void whilestat (LexState *ls, int line) { + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_patchlist(fs, luaK_jump(fs), whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +} + + +static void repeatstat (LexState *ls, int line) { + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + chunk(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (!bl2.upval) { /* no upvalues? */ + leaveblock(fs); /* finish scope */ + luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */ + } + else { /* complete semantics when there are upvalues */ + breakstat(ls); /* if condition then break */ + luaK_patchtohere(ls->fs, condexit); /* else... */ + leaveblock(fs); /* finish scope... */ + luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */ + } + leaveblock(fs); /* finish loop */ +} + + +static int exp1 (LexState *ls) { + expdesc e; + int k; + expr(ls, &e); + k = e.k; + luaK_exp2nextreg(ls->fs, &e); + return k; +} + + +static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) : + luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); + luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ + luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); +} + + +static void fornum (LexState *ls, TString *varname, int line) { + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)", 0); + new_localvarliteral(ls, "(for limit)", 1); + new_localvarliteral(ls, "(for step)", 2); + new_localvar(ls, varname, 3); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else { /* default step = 1 */ + luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); +} + + +static void forlist (LexState *ls, TString *indexname) { + /* forlist -> NAME {,NAME} IN explist1 forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 0; + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)", nvars++); + new_localvarliteral(ls, "(for state)", nvars++); + new_localvarliteral(ls, "(for control)", nvars++); + /* create declared variables */ + new_localvar(ls, indexname, nvars++); + while (testnext(ls, ',')) + new_localvar(ls, str_checkname(ls), nvars++); + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist1(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); +} + + +static void forstat (LexState *ls, int line) { + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) { + case '=': fornum(ls, varname, line); break; + case ',': case TK_IN: forlist(ls, varname); break; + default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ +} + + +static int test_then_block (LexState *ls) { + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + int condexit; + luaX_next(ls); /* skip IF or ELSEIF */ + condexit = cond(ls); + checknext(ls, TK_THEN); + block(ls); /* `then' part */ + return condexit; +} + + +static void ifstat (LexState *ls, int line) { + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int flist; + int escapelist = NO_JUMP; + flist = test_then_block(ls); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + flist = test_then_block(ls); /* ELSEIF cond THEN block */ + } + if (ls->t.token == TK_ELSE) { + luaK_concat(fs, &escapelist, luaK_jump(fs)); + luaK_patchtohere(fs, flist); + luaX_next(ls); /* skip ELSE (after patch, for correct line info) */ + block(ls); /* `else' part */ + } + else + luaK_concat(fs, &escapelist, flist); + luaK_patchtohere(fs, escapelist); + check_match(ls, TK_END, TK_IF, line); +} + + +static void localfunc (LexState *ls) { + expdesc v, b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls), 0); + init_exp(&v, VLOCAL, fs->freereg); + luaK_reserveregs(fs, 1); + adjustlocalvars(ls, 1); + body(ls, &b, 0, ls->linenumber); + luaK_storevar(fs, &v, &b); + /* debug information will only see the variable after this point! */ + getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; +} + + +static void localstat (LexState *ls) { + /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ + int nvars = 0; + int nexps; + expdesc e; + do { + new_localvar(ls, str_checkname(ls), nvars++); + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist1(ls, &e); + else { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); +} + + +static int funcname (LexState *ls, expdesc *v) { + /* funcname -> NAME {field} [`:' NAME] */ + int needself = 0; + singlevar(ls, v); + while (ls->t.token == '.') + field(ls, v); + if (ls->t.token == ':') { + needself = 1; + field(ls, v); + } + return needself; +} + + +static void funcstat (LexState *ls, int line) { + /* funcstat -> FUNCTION funcname body */ + int needself; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + needself = funcname(ls, &v); + body(ls, &b, needself, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +} + + +static void exprstat (LexState *ls) { + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + primaryexp(ls, &v.v); + if (v.v.k == VCALL) /* stat -> func */ + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + else { /* stat -> assignment */ + v.prev = NULL; + assignment(ls, &v, 1); + } +} + + +static void retstat (LexState *ls) { + /* stat -> RETURN explist */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + luaX_next(ls); /* skip RETURN */ + if (block_follow(ls->t.token) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else { + nret = explist1(ls, &e); /* optional return values */ + if (hasmultret(e.k)) { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) { /* tail call? */ + SET_OPCODE(getcode(fs,&e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); +} + + +static int statement (LexState *ls) { + int line = ls->linenumber; /* may be needed for error messages */ + switch (ls->t.token) { + case TK_IF: { /* stat -> ifstat */ + ifstat(ls, line); + return 0; + } + case TK_WHILE: { /* stat -> whilestat */ + whilestat(ls, line); + return 0; + } + case TK_DO: { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + return 0; + } + case TK_FOR: { /* stat -> forstat */ + forstat(ls, line); + return 0; + } + case TK_REPEAT: { /* stat -> repeatstat */ + repeatstat(ls, line); + return 0; + } + case TK_FUNCTION: { + funcstat(ls, line); /* stat -> funcstat */ + return 0; + } + case TK_LOCAL: { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + return 0; + } + case TK_RETURN: { /* stat -> retstat */ + retstat(ls); + return 1; /* must be last statement */ + } + case TK_BREAK: { /* stat -> breakstat */ + luaX_next(ls); /* skip BREAK */ + breakstat(ls); + return 1; /* must be last statement */ + } + default: { + exprstat(ls); + return 0; /* to avoid warnings */ + } + } +} + + +static void chunk (LexState *ls) { + /* chunk -> { stat [`;'] } */ + int islast = 0; + enterlevel(ls); + while (!islast && !block_follow(ls->t.token)) { + islast = statement(ls); + testnext(ls, ';'); + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + } + leavelevel(ls); +} + +/* }====================================================================== */ diff --git a/src/mod/legacy/languages/mod_lua/lua/lparser.h b/src/mod/legacy/languages/mod_lua/lua/lparser.h new file mode 100644 index 0000000000..18836afd1c --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lparser.h @@ -0,0 +1,82 @@ +/* +** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression descriptor +*/ + +typedef enum { + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in `upvalues' */ + VGLOBAL, /* info = index of table; aux = index of global name in `k' */ + VINDEXED, /* info = table register; aux = index register (or `k') */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VNONRELOC, /* info = result register */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ +} expkind; + +typedef struct expdesc { + expkind k; + union { + struct { int info, aux; } s; + lua_Number nval; + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ +} expdesc; + + +typedef struct upvaldesc { + lu_byte k; + lu_byte info; +} upvaldesc; + + +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct lua_State *L; /* copy of the Lua state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* `pc' of last `jump target' */ + int jpc; /* list of pending jumps to `pc' */ + int freereg; /* first free register */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + short nlocvars; /* number of elements in `locvars' */ + lu_byte nactvar; /* number of active local variables */ + upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */ + unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */ +} FuncState; + + +LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + const char *name); + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lstate.c b/src/mod/legacy/languages/mod_lua/lua/lstate.c new file mode 100644 index 0000000000..4313b83a0c --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lstate.c @@ -0,0 +1,214 @@ +/* +** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstate_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "llex.h" +#include "lmem.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + +#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE) +#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE) +#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE)) + + +/* +** Main thread combines a thread state and the global state +*/ +typedef struct LG { + lua_State l; + global_State g; +} LG; + + + +static void stack_init (lua_State *L1, lua_State *L) { + /* initialize CallInfo array */ + L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo); + L1->ci = L1->base_ci; + L1->size_ci = BASIC_CI_SIZE; + L1->end_ci = L1->base_ci + L1->size_ci - 1; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); + L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; + L1->top = L1->stack; + L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; + /* initialize first ci */ + L1->ci->func = L1->top; + setnilvalue(L1->top++); /* `function' entry for this `ci' */ + L1->base = L1->ci->base = L1->top; + L1->ci->top = L1->top + LUA_MINSTACK; +} + + +static void freestack (lua_State *L, lua_State *L1) { + luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); + luaM_freearray(L, L1->stack, L1->stacksize, TValue); +} + + +/* +** open parts that may cause memory-allocation errors +*/ +static void f_luaopen (lua_State *L, void *ud) { + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */ + sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + luaS_fix(luaS_newliteral(L, MEMERRMSG)); + g->GCthreshold = 4*g->totalbytes; +} + + +static void preinit_state (lua_State *L, global_State *g) { + G(L) = g; + L->stack = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->size_ci = 0; + L->nCcalls = L->baseCcalls = 0; + L->status = 0; + L->base_ci = L->ci = NULL; + L->savedpc = NULL; + L->errfunc = 0; + setnilvalue(gt(L)); +} + + +static void close_state (lua_State *L) { + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeall(L); /* collect all objects */ + lua_assert(g->rootgc == obj2gco(L)); + lua_assert(g->strt.nuse == 0); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); + luaZ_freebuffer(L, &g->buff); + freestack(L, L); + lua_assert(g->totalbytes == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); +} + + +lua_State *luaE_newthread (lua_State *L) { + lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); + luaC_link(L, obj2gco(L1), LUA_TTHREAD); + preinit_state(L1, G(L)); + stack_init(L1, L); /* init stack */ + setobj2n(L, gt(L1), gt(L)); /* share table of globals */ + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + lua_assert(iswhite(obj2gco(L1))); + return L1; +} + + +void luaE_freethread (lua_State *L, lua_State *L1) { + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L1); + freestack(L, L1); + luaM_freemem(L, fromstate(L1), state_size(lua_State)); +} + + +LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { + int i; + lua_State *L; + global_State *g; + void *l = (*f)(ud, NULL, 0, state_size(LG)); + if (l == NULL) return NULL; + L = tostate(l); + g = &((LG *)L)->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + set2bits(L->marked, FIXEDBIT, SFIXEDBIT); + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->GCthreshold = 0; /* mark it as unfinished state */ + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(registry(L)); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->gcstate = GCSpause; + g->rootgc = obj2gco(L); + g->sweepstrgc = 0; + g->sweepgc = &g->rootgc; + g->gray = NULL; + g->grayagain = NULL; + g->weak = NULL; + g->tmudata = NULL; + g->totalbytes = sizeof(LG); + g->gcpause = LUAI_GCPAUSE; + g->gcstepmul = LUAI_GCMUL; + g->gcdept = 0; + for (i=0; imt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + else + luai_userstateopen(L); + return L; +} + + +static void callallgcTM (lua_State *L, void *ud) { + UNUSED(ud); + luaC_callGCTM(L); /* call GC metamethods for all udata */ +} + + +LUA_API void lua_close (lua_State *L) { + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_separateudata(L, 1); /* separate udata that have GC metamethods */ + L->errfunc = 0; /* no error function during GC metamethods */ + do { /* repeat until no more errors */ + L->ci = L->base_ci; + L->base = L->top = L->ci->base; + L->nCcalls = L->baseCcalls = 0; + } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); + lua_assert(G(L)->tmudata == NULL); + luai_userstateclose(L); + close_state(L); +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lstate.h b/src/mod/legacy/languages/mod_lua/lua/lstate.h new file mode 100644 index 0000000000..3bc575b6bc --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lstate.h @@ -0,0 +1,169 @@ +/* +** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* table of globals */ +#define gt(L) (&L->l_gt) + +/* registry */ +#define registry(L) (&G(L)->l_registry) + + +/* extra stack space to handle TM calls and some other extras */ +#define EXTRA_STACK 5 + + +#define BASIC_CI_SIZE 8 + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + + + +typedef struct stringtable { + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** informations about a call +*/ +typedef struct CallInfo { + StkId base; /* base for this function */ + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + const Instruction *savedpc; + int nresults; /* expected number of results from this function */ + int tailcalls; /* number of tail calls lost under this entry */ +} CallInfo; + + + +#define curr_func(L) (clvalue(L->ci->func)) +#define ci_func(ci) (clvalue((ci)->func)) +#define f_isLua(ci) (!ci_func(ci)->c.isC) +#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci)) + + +/* +** `global state', shared by all threads of this state +*/ +typedef struct global_State { + stringtable strt; /* hash table for strings */ + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *rootgc; /* list of all collectable objects */ + GCObject **sweepgc; /* position of sweep in `rootgc' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of weak tables (to be cleared) */ + GCObject *tmudata; /* last element of list of userdata to be GC */ + Mbuffer buff; /* temporary buffer for string concatentation */ + lu_mem GCthreshold; + lu_mem totalbytes; /* number of bytes currently allocated */ + lu_mem estimate; /* an estimate of number of bytes actually in use */ + lu_mem gcdept; /* how much GC is `behind schedule' */ + int gcpause; /* size of pause between successive GCs */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + TValue l_registry; + struct lua_State *mainthread; + UpVal uvhead; /* head of double-linked list of all open upvalues */ + struct Table *mt[NUM_TAGS]; /* metatables for basic types */ + TString *tmname[TM_N]; /* array with tag-method names */ +} global_State; + + +/* +** `per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + StkId base; /* base of current function */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *savedpc; /* `savedpc' of current function */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + CallInfo *end_ci; /* points after end of ci array*/ + CallInfo *base_ci; /* array of CallInfo's */ + int stacksize; + int size_ci; /* size of array `base_ci' */ + unsigned short nCcalls; /* number of nested C calls */ + unsigned short baseCcalls; /* nested C calls when resuming coroutine */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + TValue l_gt; /* table of globals */ + TValue env; /* temporary place for environments */ + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ +}; + + +#define G(L) (L->l_G) + + +/* +** Union of all collectable objects +*/ +union GCObject { + GCheader gch; + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ +}; + + +/* macros to convert a GCObject into a specific value */ +#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) +#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define ngcotouv(o) \ + check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) + +/* macro to convert any Lua object into a GCObject */ +#define obj2gco(v) (cast(GCObject *, (v))) + + +LUAI_FUNC lua_State *luaE_newthread (lua_State *L); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); + +#endif + diff --git a/src/mod/legacy/languages/mod_lua/lua/lstring.c b/src/mod/legacy/languages/mod_lua/lua/lstring.c new file mode 100644 index 0000000000..49113151cc --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lstring.c @@ -0,0 +1,111 @@ +/* +** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keeps all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + + +#include + +#define lstring_c +#define LUA_CORE + +#include "lua.h" + +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" + + + +void luaS_resize (lua_State *L, int newsize) { + GCObject **newhash; + stringtable *tb; + int i; + if (G(L)->gcstate == GCSsweepstring) + return; /* cannot resize during GC traverse */ + newhash = luaM_newvector(L, newsize, GCObject *); + tb = &G(L)->strt; + for (i=0; isize; i++) { + GCObject *p = tb->hash[i]; + while (p) { /* for each node in the list */ + GCObject *next = p->gch.next; /* save next */ + unsigned int h = gco2ts(p)->hash; + int h1 = lmod(h, newsize); /* new position */ + lua_assert(cast_int(h%newsize) == lmod(h, newsize)); + p->gch.next = newhash[h1]; /* chain it */ + newhash[h1] = p; + p = next; + } + } + luaM_freearray(L, tb->hash, tb->size, TString *); + tb->size = newsize; + tb->hash = newhash; +} + + +static TString *newlstr (lua_State *L, const char *str, size_t l, + unsigned int h) { + TString *ts; + stringtable *tb; + if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) + luaM_toobig(L); + ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.marked = luaC_white(G(L)); + ts->tsv.tt = LUA_TSTRING; + ts->tsv.reserved = 0; + memcpy(ts+1, str, l*sizeof(char)); + ((char *)(ts+1))[l] = '\0'; /* ending 0 */ + tb = &G(L)->strt; + h = lmod(h, tb->size); + ts->tsv.next = tb->hash[h]; /* chain new entry */ + tb->hash[h] = obj2gco(ts); + tb->nuse++; + if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) + luaS_resize(L, tb->size*2); /* too crowded */ + return ts; +} + + +TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { + GCObject *o; + unsigned int h = cast(unsigned int, l); /* seed */ + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1=l; l1>=step; l1-=step) /* compute hash */ + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; + o != NULL; + o = o->gch.next) { + TString *ts = rawgco2ts(o); + if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { + /* string may be dead */ + if (isdead(G(L), o)) changewhite(o); + return ts; + } + } + return newlstr(L, str, l, h); /* not found */ +} + + +Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata))); + u->uv.marked = luaC_white(G(L)); /* is not finalized */ + u->uv.tt = LUA_TUSERDATA; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + /* chain it on udata list (after main thread) */ + u->uv.next = G(L)->mainthread->next; + G(L)->mainthread->next = obj2gco(u); + return u; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lstring.h b/src/mod/legacy/languages/mod_lua/lua/lstring.h new file mode 100644 index 0000000000..73a2ff8b38 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lstring.h @@ -0,0 +1,31 @@ +/* +** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) + +#define sizeudata(u) (sizeof(union Udata)+(u)->len) + +#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) + +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lstrlib.c b/src/mod/legacy/languages/mod_lua/lua/lstrlib.c new file mode 100644 index 0000000000..1b4763d4ee --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lstrlib.c @@ -0,0 +1,869 @@ +/* +** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $ +** Standard library for string operations and pattern-matching +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include +#include + +#define lstrlib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* macro to `unsign' a character */ +#define uchar(c) ((unsigned char)(c)) + + + +static int str_len (lua_State *L) { + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, l); + return 1; +} + + +static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) { + /* relative string position: negative means back from end */ + if (pos < 0) pos += (ptrdiff_t)len + 1; + return (pos >= 0) ? pos : 0; +} + + +static int str_sub (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l); + ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > (ptrdiff_t)l) end = (ptrdiff_t)l; + if (start <= end) + lua_pushlstring(L, s+start-1, end-start+1); + else lua_pushliteral(L, ""); + return 1; +} + + +static int str_reverse (lua_State *L) { + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + while (l--) luaL_addchar(&b, s[l]); + luaL_pushresult(&b); + return 1; +} + + +static int str_lower (lua_State *L) { + size_t l; + size_t i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + for (i=0; i 0) + luaL_addlstring(&b, s, l); + luaL_pushresult(&b); + return 1; +} + + +static int str_byte (lua_State *L) { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l); + ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l); + int n, i; + if (posi <= 0) posi = 1; + if ((size_t)pose > l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* overflow? */ + luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index"); + return l; +} + + +static int capture_to_close (MatchState *ms) { + int level = ms->level; + for (level--; level>=0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); +} + + +static const char *classend (MatchState *ms, const char *p) { + switch (*p++) { + case L_ESC: { + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p+1; + } + case '[': { + if (*p == '^') p++; + do { /* look for a `]' */ + if (*p == '\0') + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && *p != '\0') + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p+1; + } + default: { + return p; + } + } +} + + +static int match_class (int c, int cl) { + int res; + switch (tolower(cl)) { + case 'a' : res = isalpha(c); break; + case 'c' : res = iscntrl(c); break; + case 'd' : res = isdigit(c); break; + case 'l' : res = islower(c); break; + case 'p' : res = ispunct(c); break; + case 's' : res = isspace(c); break; + case 'u' : res = isupper(c); break; + case 'w' : res = isalnum(c); break; + case 'x' : res = isxdigit(c); break; + case 'z' : res = (c == 0); break; + default: return (cl == c); + } + return (islower(cl) ? res : !res); +} + + +static int matchbracketclass (int c, const char *p, const char *ec) { + int sig = 1; + if (*(p+1) == '^') { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) { + if (*p == L_ESC) { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p+1) == '-') && (p+2 < ec)) { + p+=2; + if (uchar(*(p-2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) return sig; + } + return !sig; +} + + +static int singlematch (int c, const char *p, const char *ep) { + switch (*p) { + case '.': return 1; /* matches any char */ + case L_ESC: return match_class(c, uchar(*(p+1))); + case '[': return matchbracketclass(c, p, ep-1); + default: return (uchar(*p) == c); + } +} + + +static const char *match (MatchState *ms, const char *s, const char *p); + + +static const char *matchbalance (MatchState *ms, const char *s, + const char *p) { + if (*p == 0 || *(p+1) == 0) + luaL_error(ms->L, "unbalanced pattern"); + if (*s != *p) return NULL; + else { + int b = *p; + int e = *(p+1); + int cont = 1; + while (++s < ms->src_end) { + if (*s == e) { + if (--cont == 0) return s+1; + } + else if (*s == b) cont++; + } + } + return NULL; /* string ends out of balance */ +} + + +static const char *max_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + ptrdiff_t i = 0; /* counts maximum expand for item */ + while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i>=0) { + const char *res = match(ms, (s+i), ep+1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; +} + + +static const char *min_expand (MatchState *ms, const char *s, + const char *p, const char *ep) { + for (;;) { + const char *res = match(ms, s, ep+1); + if (res != NULL) + return res; + else if (ssrc_end && singlematch(uchar(*s), p, ep)) + s++; /* try with one more repetition */ + else return NULL; + } +} + + +static const char *start_capture (MatchState *ms, const char *s, + const char *p, int what) { + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level+1; + if ((res=match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; +} + + +static const char *end_capture (MatchState *ms, const char *s, + const char *p) { + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; +} + + +static const char *match_capture (MatchState *ms, const char *s, int l) { + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end-s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s+len; + else return NULL; +} + + +static const char *match (MatchState *ms, const char *s, const char *p) { + init: /* using goto's to optimize tail recursion */ + switch (*p) { + case '(': { /* start capture */ + if (*(p+1) == ')') /* position capture? */ + return start_capture(ms, s, p+2, CAP_POSITION); + else + return start_capture(ms, s, p+1, CAP_UNFINISHED); + } + case ')': { /* end capture */ + return end_capture(ms, s, p+1); + } + case L_ESC: { + switch (*(p+1)) { + case 'b': { /* balanced string? */ + s = matchbalance(ms, s, p+2); + if (s == NULL) return NULL; + p+=4; goto init; /* else return match(ms, s, p+4); */ + } + case 'f': { /* frontier? */ + const char *ep; char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " + LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s-1); + if (matchbracketclass(uchar(previous), p, ep-1) || + !matchbracketclass(uchar(*s), p, ep-1)) return NULL; + p=ep; goto init; /* else return match(ms, s, ep); */ + } + default: { + if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p+1))); + if (s == NULL) return NULL; + p+=2; goto init; /* else return match(ms, s, p+2) */ + } + goto dflt; /* case default */ + } + } + } + case '\0': { /* end of pattern */ + return s; /* match succeeded */ + } + case '$': { + if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ + return (s == ms->src_end) ? s : NULL; /* check end of string */ + else goto dflt; + } + default: dflt: { /* it is a pattern item */ + const char *ep = classend(ms, p); /* points to what is next */ + int m = ssrc_end && singlematch(uchar(*s), p, ep); + switch (*ep) { + case '?': { /* optional */ + const char *res; + if (m && ((res=match(ms, s+1, ep+1)) != NULL)) + return res; + p=ep+1; goto init; /* else return match(ms, s, ep+1); */ + } + case '*': { /* 0 or more repetitions */ + return max_expand(ms, s, p, ep); + } + case '+': { /* 1 or more repetitions */ + return (m ? max_expand(ms, s+1, p, ep) : NULL); + } + case '-': { /* 0 or more repetitions (minimum) */ + return min_expand(ms, s, p, ep); + } + default: { + if (!m) return NULL; + s++; p=ep; goto init; /* else return match(ms, s+1, ep); */ + } + } + } + } +} + + + +static const char *lmemfind (const char *s1, size_t l1, + const char *s2, size_t l2) { + if (l2 == 0) return s1; /* empty strings are everywhere */ + else if (l2 > l1) return NULL; /* avoids a negative `l1' */ + else { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1-l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { + init++; /* 1st char is already checked */ + if (memcmp(init, s2+1, l2) == 0) + return init-1; + else { /* correct `l1' and `s1' to try again */ + l1 -= init-s1; + s1 = init; + } + } + return NULL; /* not found */ + } +} + + +static void push_onecapture (MatchState *ms, int i, const char *s, + const char *e) { + if (i >= ms->level) { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } +} + + +static int push_captures (MatchState *ms, const char *s, const char *e) { + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ +} + + +static int str_find_aux (lua_State *L, int find) { + size_t l1, l2; + const char *s = luaL_checklstring(L, 1, &l1); + const char *p = luaL_checklstring(L, 2, &l2); + ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; + if (init < 0) init = 0; + else if ((size_t)(init) > l1) init = (ptrdiff_t)l1; + if (find && (lua_toboolean(L, 4) || /* explicit request? */ + strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ + /* do a plain search */ + const char *s2 = lmemfind(s+init, l1-init, p, l2); + if (s2) { + lua_pushinteger(L, s2-s+1); + lua_pushinteger(L, s2-s+l2); + return 2; + } + } + else { + MatchState ms; + int anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1=s+init; + ms.L = L; + ms.src_init = s; + ms.src_end = s+l1; + do { + const char *res; + ms.level = 0; + if ((res=match(&ms, s1, p)) != NULL) { + if (find) { + lua_pushinteger(L, s1-s+1); /* start */ + lua_pushinteger(L, res-s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; +} + + +static int str_find (lua_State *L) { + return str_find_aux(L, 1); +} + + +static int str_match (lua_State *L) { + return str_find_aux(L, 0); +} + + +static int gmatch_aux (lua_State *L) { + MatchState ms; + size_t ls; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tostring(L, lua_upvalueindex(2)); + const char *src; + ms.L = L; + ms.src_init = s; + ms.src_end = s+ls; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) { + const char *e; + ms.level = 0; + if ((e = match(&ms, src, p)) != NULL) { + lua_Integer newstart = e-s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ +} + + +static int gmatch (lua_State *L) { + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; +} + + +static int gfind_nodef (lua_State *L) { + return luaL_error(L, LUA_QL("string.gfind") " was renamed to " + LUA_QL("string.gmatch")); +} + + +static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) + luaL_addchar(b, news[i]); + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } +} + + +static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) { + lua_State *L = ms->L; + switch (lua_type(L, 3)) { + case LUA_TNUMBER: + case LUA_TSTRING: { + add_s(ms, b, s, e); + return; + } + case LUA_TFUNCTION: { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + } + if (!lua_toboolean(L, -1)) { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ +} + + +static int str_gsub (lua_State *L) { + size_t srcl; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checkstring(L, 2); + int tr = lua_type(L, 3); + int max_s = luaL_optint(L, 4, srcl+1); + int anchor = (*p == '^') ? (p++, 1) : 0; + int n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || + tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + ms.L = L; + ms.src_init = src; + ms.src_end = src+srcl; + while (n < max_s) { + const char *e; + ms.level = 0; + e = match(&ms, src, p); + if (e) { + n++; + add_value(&ms, &b, src, e); + } + if (e && e>src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end-src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; +} + +/* }====================================================== */ + + +/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ +#define MAX_ITEM 512 +/* valid flags in a format specification */ +#define FLAGS "-+ #0" +/* +** maximum size of each format specification (such as '%-099.99d') +** (+10 accounts for %99.99x plus margin of error) +*/ +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) + + +static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) { + switch (*s) { + case '"': case '\\': case '\n': { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + break; + } + case '\r': { + luaL_addlstring(b, "\\r", 2); + break; + } + case '\0': { + luaL_addlstring(b, "\\000", 4); + break; + } + default: { + luaL_addchar(b, *s); + break; + } + } + s++; + } + luaL_addchar(b, '"'); +} + +static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + strncpy(form, strfrmt, p - strfrmt + 1); + form += p - strfrmt + 1; + *form = '\0'; + return p; +} + + +static void addintlen (char *form) { + size_t l = strlen(form); + char spec = form[l - 1]; + strcpy(form + l - 1, LUA_INTFRMLEN); + form[l + sizeof(LUA_INTFRMLEN) - 2] = spec; + form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0'; +} + + +static int str_format (lua_State *L) { + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt+sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char buff[MAX_ITEM]; /* to store the formatted item */ + arg++; + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) { + case 'c': { + sprintf(buff, form, (int)luaL_checknumber(L, arg)); + break; + } + case 'd': case 'i': { + addintlen(form); + sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'o': case 'u': case 'x': case 'X': { + addintlen(form); + sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'e': case 'E': case 'f': + case 'g': case 'G': { + sprintf(buff, form, (double)luaL_checknumber(L, arg)); + break; + } + case 'q': { + addquoted(L, &b, arg); + continue; /* skip the 'addsize' at the end */ + } + case 's': { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) { + /* no precision and string is too long to be formatted; + keep original string */ + lua_pushvalue(L, arg); + luaL_addvalue(&b); + continue; /* skip the `addsize' at the end */ + } + else { + sprintf(buff, form, s); + break; + } + } + default: { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " + LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addlstring(&b, buff, strlen(buff)); + } + } + luaL_pushresult(&b); + return 1; +} + + +static const luaL_Reg strlib[] = { + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gfind", gfind_nodef}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL} +}; + + +static void createmetatable (lua_State *L) { + lua_createtable(L, 0, 1); /* create metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); + lua_setmetatable(L, -2); /* set string metatable */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* string library... */ + lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ + lua_pop(L, 1); /* pop metatable */ +} + + +/* +** Open string library +*/ +LUALIB_API int luaopen_string (lua_State *L) { + luaL_register(L, LUA_STRLIBNAME, strlib); +#if defined(LUA_COMPAT_GFIND) + lua_getfield(L, -1, "gmatch"); + lua_setfield(L, -2, "gfind"); +#endif + createmetatable(L); + return 1; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/ltable.c b/src/mod/legacy/languages/mod_lua/lua/ltable.c new file mode 100644 index 0000000000..ec84f4fabc --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ltable.c @@ -0,0 +1,588 @@ +/* +** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + + +/* +** Implementation of tables (aka arrays, objects, or hash tables). +** Tables keep its elements in two parts: an array part and a hash part. +** Non-negative integer keys are all candidates to be kept in the array +** part. The actual size of the array is the largest `n' such that at +** least half the slots between 0 and n are in use. +** Hash uses a mix of chained scatter table with Brent's variation. +** A main invariant of these tables is that, if an element is not +** in its main position (i.e. the `original' position that its hash gives +** to it), then the colliding element is in its own main position. +** Hence even when the load factor reaches 100%, performance remains good. +*/ + +#include +#include + +#define ltable_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lgc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstate.h" +#include "ltable.h" + + +/* +** max size of array part is 2^MAXBITS +*/ +#if LUAI_BITSINT > 26 +#define MAXBITS 26 +#else +#define MAXBITS (LUAI_BITSINT-2) +#endif + +#define MAXASIZE (1 << MAXBITS) + + +#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) + +#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t,p) hashpow2(t, p) + + +/* +** for some types, it is better to avoid modulus by power of 2, as +** they tend to have many 2 factors. +*/ +#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) + + +#define hashpointer(t,p) hashmod(t, IntPoint(p)) + + +/* +** number of ints inside a lua_Number +*/ +#define numints cast_int(sizeof(lua_Number)/sizeof(int)) + + + +#define dummynode (&dummynode_) + +static const Node dummynode_ = { + {{NULL}, LUA_TNIL}, /* value */ + {{{NULL}, LUA_TNIL, NULL}} /* key */ +}; + + +/* +** hash for lua_Numbers +*/ +static Node *hashnum (const Table *t, lua_Number n) { + unsigned int a[numints]; + int i; + if (luai_numeq(n, 0)) /* avoid problems with -0 */ + return gnode(t, 0); + memcpy(a, &n, sizeof(a)); + for (i = 1; i < numints; i++) a[0] += a[i]; + return hashmod(t, a[0]); +} + + + +/* +** returns the `main' position of an element in a table (that is, the index +** of its hash value) +*/ +static Node *mainposition (const Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TSTRING: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } +} + + +/* +** returns the index for `key' if `key' is an appropriate key to live in +** the array part of the table, -1 otherwise. +*/ +static int arrayindex (const TValue *key) { + if (ttisnumber(key)) { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ +} + + +/* +** returns the index of a `key' for table traversals. First goes all +** elements in the array part, then elements in the hash part. The +** beginning of a traversal is signalled by -1. +*/ +static int findindex (lua_State *L, Table *t, StkId key) { + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i-1; /* yes; that's the index (corrected to C) */ + else { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaO_rawequalObj(key2tval(n), key) || + (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && + gcvalue(gkey(n)) == gcvalue(key))) { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else n = gnext(n); + } while (n); + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + return 0; /* to avoid warnings */ + } +} + + +int luaH_next (lua_State *L, Table *t, StkId key) { + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) { /* try first array part */ + if (!ttisnil(&t->array[i])) { /* a non-nil value? */ + setnvalue(key, cast_num(i+1)); + setobj2s(L, key+1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ + setobj2s(L, key, key2tval(gnode(t, i))); + setobj2s(L, key+1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ +} + + +/* +** {============================================================= +** Rehash +** ============================================================== +*/ + + +static int computesizes (int nums[], int *narray) { + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { + if (nums[i] > 0) { + a += nums[i]; + if (a > twotoi/2) { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray/2 <= na && na <= *narray); + return na; +} + + +static int countint (const TValue *key, int *nums) { + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ + nums[ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; +} + + +static int numusearray (const Table *t, int *nums) { + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) { + if (!ttisnil(&t->array[i-1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; +} + + +static int numusehash (const Table *t, int *nums, int *pnasize) { + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) { + ause += countint(key2tval(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; +} + + +static void setarrayvector (lua_State *L, Table *t, int size) { + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i=t->sizearray; iarray[i]); + t->sizearray = size; +} + + +static void setnodevector (lua_State *L, Table *t, int size) { + int lsize; + if (size == 0) { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else { + int i; + lsize = ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i=0; ilsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ +} + + +static void resize (lua_State *L, Table *t, int nasize, int nhsize) { + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i=nasize; iarray[i])) + setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) { + Node *old = nold+i; + if (!ttisnil(gval(old))) + setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old)); + } + if (nold != dummynode) + luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ +} + + +void luaH_resizearray (lua_State *L, Table *t, int nasize) { + int nsize = (t->node == dummynode) ? 0 : sizenode(t); + resize(L, t, nasize, nsize); +} + + +static void rehash (lua_State *L, Table *t, const TValue *ek) { + int nasize, na; + int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ + int i; + int totaluse; + for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + resize(L, t, nasize, totaluse - na); +} + + + +/* +** }============================================================= +*/ + + +Table *luaH_new (lua_State *L, int narray, int nhash) { + Table *t = luaM_new(L, Table); + luaC_link(L, obj2gco(t), LUA_TTABLE); + t->metatable = NULL; + t->flags = cast_byte(~0); + /* temporary values (kept only if some malloc fails) */ + t->array = NULL; + t->sizearray = 0; + t->lsizenode = 0; + t->node = cast(Node *, dummynode); + setarrayvector(L, t, narray); + setnodevector(L, t, nhash); + return t; +} + + +void luaH_free (lua_State *L, Table *t) { + if (t->node != dummynode) + luaM_freearray(L, t->node, sizenode(t), Node); + luaM_freearray(L, t->array, t->sizearray, TValue); + luaM_free(L, t); +} + + +static Node *getfreepos (Table *t) { + while (t->lastfree-- > t->node) { + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ +} + + + +/* +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. +*/ +static TValue *newkey (lua_State *L, Table *t, const TValue *key) { + Node *mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || mp == dummynode) { + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + return luaH_set(L, t, key); /* re-insert key into grown table */ + } + lua_assert(n != dummynode); + othern = mainposition(t, key2tval(mp)); + if (othern != mp) { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + gkey(mp)->value = key->value; gkey(mp)->tt = key->tt; + luaC_barriert(L, t, key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); +} + + +/* +** search function for integers +*/ +const TValue *luaH_getnum (Table *t, int key) { + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) + return &t->array[key-1]; + else { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } +} + + +/* +** search function for strings +*/ +const TValue *luaH_getstr (Table *t, TString *key) { + Node *n = hashstr(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; +} + + +/* +** main search function +*/ +const TValue *luaH_get (Table *t, const TValue *key) { + switch (ttype(key)) { + case LUA_TNIL: return luaO_nilobject; + case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNUMBER: { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */ + return luaH_getnum(t, k); /* use specialized version */ + /* else go through */ + } + default: { + Node *n = mainposition(t, key); + do { /* check whether `key' is somewhere in the chain */ + if (luaO_rawequalObj(key2tval(n), key)) + return gval(n); /* that's it */ + else n = gnext(n); + } while (n); + return luaO_nilobject; + } + } +} + + +TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { + const TValue *p = luaH_get(t, key); + t->flags = 0; + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + if (ttisnil(key)) luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(nvalue(key))) + luaG_runerror(L, "table index is NaN"); + return newkey(L, t, key); + } +} + + +TValue *luaH_setnum (lua_State *L, Table *t, int key) { + const TValue *p = luaH_getnum(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setnvalue(&k, cast_num(key)); + return newkey(L, t, &k); + } +} + + +TValue *luaH_setstr (lua_State *L, Table *t, TString *key) { + const TValue *p = luaH_getstr(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else { + TValue k; + setsvalue(L, &k, key); + return newkey(L, t, &k); + } +} + + +static int unbound_search (Table *t, unsigned int j) { + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getnum(t, j))) { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getnum(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(luaH_getnum(t, m))) j = m; + else i = m; + } + return i; +} + + +/* +** Try to find a boundary in table `t'. A `boundary' is an integer index +** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). +*/ +int luaH_getn (Table *t) { + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) { + unsigned int m = (i+j)/2; + if (ttisnil(&t->array[m - 1])) j = m; + else i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (t->node == dummynode) /* hash part is empty? */ + return j; /* that is easy... */ + else return unbound_search(t, j); +} + + + +#if defined(LUA_DEBUG) + +Node *luaH_mainposition (const Table *t, const TValue *key) { + return mainposition(t, key); +} + +int luaH_isdummy (Node *n) { return n == dummynode; } + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/ltable.h b/src/mod/legacy/languages/mod_lua/lua/ltable.h new file mode 100644 index 0000000000..f5b9d5ead0 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ltable.h @@ -0,0 +1,40 @@ +/* +** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.nk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) + +#define key2tval(n) (&(n)->i_key.tvk) + + +LUAI_FUNC const TValue *luaH_getnum (Table *t, int key); +LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn (Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (Node *n); +#endif + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/ltablib.c b/src/mod/legacy/languages/mod_lua/lua/ltablib.c new file mode 100644 index 0000000000..b6d9cb4ac7 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ltablib.c @@ -0,0 +1,287 @@ +/* +** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $ +** Library for Table Manipulation +** See Copyright Notice in lua.h +*/ + + +#include + +#define ltablib_c +#define LUA_LIB + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n)) + + +static int foreachi (lua_State *L) { + int i; + int n = aux_getn(L, 1); + luaL_checktype(L, 2, LUA_TFUNCTION); + for (i=1; i <= n; i++) { + lua_pushvalue(L, 2); /* function */ + lua_pushinteger(L, i); /* 1st argument */ + lua_rawgeti(L, 1, i); /* 2nd argument */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 1); /* remove nil result */ + } + return 0; +} + + +static int foreach (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pushvalue(L, 2); /* function */ + lua_pushvalue(L, -3); /* key */ + lua_pushvalue(L, -3); /* value */ + lua_call(L, 2, 1); + if (!lua_isnil(L, -1)) + return 1; + lua_pop(L, 2); /* remove value and result */ + } + return 0; +} + + +static int maxn (lua_State *L) { + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; +} + + +static int getn (lua_State *L) { + lua_pushinteger(L, aux_getn(L, 1)); + return 1; +} + + +static int setn (lua_State *L) { + luaL_checktype(L, 1, LUA_TTABLE); +#ifndef luaL_setn + luaL_setn(L, 1, luaL_checkint(L, 2)); +#else + luaL_error(L, LUA_QL("setn") " is obsolete"); +#endif + lua_pushvalue(L, 1); + return 1; +} + + +static int tinsert (lua_State *L) { + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) { + case 2: { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + if (pos > e) e = pos; /* `grow' array if necessary */ + for (i = e; i > pos; i--) { /* move up elements */ + lua_rawgeti(L, 1, i-1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + luaL_setn(L, 1, e); /* new size */ + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int tremove (lua_State *L) { + int e = aux_getn(L, 1); + int pos = luaL_optint(L, 2, e); + if (!(1 <= pos && pos <= e)) /* position is outside bounds? */ + return 0; /* nothing to remove */ + luaL_setn(L, 1, e - 1); /* t.n = n-1 */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { + if (i>u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { + if (j + +#define ltm_c +#define LUA_CORE + +#include "lua.h" + +#include "lobject.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" + + + +const char *const luaT_typenames[] = { + "nil", "boolean", "userdata", "number", + "string", "table", "function", "userdata", "thread", + "proto", "upval" +}; + + +void luaT_init (lua_State *L) { + static const char *const luaT_eventname[] = { /* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__len", "__lt", "__le", + "__concat", "__call" + }; + int i; + for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } +} + + +/* +** function to be used with macro "fasttm": optimized for absence of +** tag methods +*/ +const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { + const TValue *tm = luaH_getstr(events, ename); + lua_assert(event <= TM_EQ); + if (ttisnil(tm)) { /* no tag method? */ + events->flags |= cast_byte(1u<metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttype(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/ltm.h b/src/mod/legacy/languages/mod_lua/lua/ltm.h new file mode 100644 index 0000000000..64343b781b --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/ltm.h @@ -0,0 +1,54 @@ +/* +** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LEN, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ +} TMS; + + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +LUAI_DATA const char *const luaT_typenames[]; + + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lua.2005.vcproj b/src/mod/legacy/languages/mod_lua/lua/lua.2005.vcproj new file mode 100644 index 0000000000..bd0b5e2e30 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lua.2005.vcproj @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/legacy/languages/mod_lua/lua/lua.2008.vcproj b/src/mod/legacy/languages/mod_lua/lua/lua.2008.vcproj new file mode 100644 index 0000000000..4004e21b27 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lua.2008.vcproj @@ -0,0 +1,531 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/legacy/languages/mod_lua/lua/lua.2010.vcxproj b/src/mod/legacy/languages/mod_lua/lua/lua.2010.vcxproj new file mode 100644 index 0000000000..dbf8aefb92 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lua.2010.vcxproj @@ -0,0 +1,187 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + lua51 + {D0B36172-CD76-454A-9B89-990025266C2A} + lua51 + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + .;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + 4127; 4505;%(DisableSpecificWarnings) + false + + + true + false + MachineX86 + + + + + X64 + + + .;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + 4127; 4505;%(DisableSpecificWarnings) + false + + + true + false + MachineX64 + + + + + .;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDLL + 4127; 4505;%(DisableSpecificWarnings) + + + false + MachineX86 + + + + + X64 + + + .;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDLL + 4127; 4505;%(DisableSpecificWarnings) + + + false + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/mod/legacy/languages/mod_lua/lua/lua.2012.vcxproj b/src/mod/legacy/languages/mod_lua/lua/lua.2012.vcxproj new file mode 100644 index 0000000000..17f7b5eae4 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lua.2012.vcxproj @@ -0,0 +1,191 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + lua51 + {D0B36172-CD76-454A-9B89-990025266C2A} + lua51 + Win32Proj + + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + .;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + 4127; 4505;%(DisableSpecificWarnings) + false + + + true + false + MachineX86 + + + + + X64 + + + .;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + 4127; 4505;%(DisableSpecificWarnings) + false + + + true + false + MachineX64 + + + + + .;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDLL + 4127; 4505;%(DisableSpecificWarnings) + + + false + MachineX86 + + + + + X64 + + + .;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;LUA_BUILD_AS_DLL;%(PreprocessorDefinitions) + MultiThreadedDLL + 4127; 4505;%(DisableSpecificWarnings) + + + false + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/legacy/languages/mod_lua/lua/lua.c b/src/mod/legacy/languages/mod_lua/lua/lua.c new file mode 100644 index 0000000000..3a46609328 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lua.c @@ -0,0 +1,392 @@ +/* +** $Id: lua.c,v 1.160.1.2 2007/12/28 15:32:23 roberto Exp $ +** Lua stand-alone interpreter +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include +#include + +#define lua_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +static lua_State *globalL = NULL; + +static const char *progname = LUA_PROGNAME; + + + +static void lstop (lua_State *L, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); +} + + +static void laction (int i) { + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +} + + +static void print_usage (void) { + fprintf(stderr, + "usage: %s [options] [script [args]].\n" + "Available options are:\n" + " -e stat execute string " LUA_QL("stat") "\n" + " -l name require library " LUA_QL("name") "\n" + " -i enter interactive mode after executing " LUA_QL("script") "\n" + " -v show version information\n" + " -- stop handling options\n" + " - execute stdin and stop handling options\n" + , + progname); + fflush(stderr); +} + + +static void l_message (const char *pname, const char *msg) { + if (pname) fprintf(stderr, "%s: ", pname); + fprintf(stderr, "%s\n", msg); + fflush(stderr); +} + + +static int report (lua_State *L, int status) { + if (status && !lua_isnil(L, -1)) { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } + return status; +} + + +static int traceback (lua_State *L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; +} + + +static int docall (lua_State *L, int narg, int clear) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + signal(SIGINT, laction); + status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); + signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + /* force a complete garbage collection in case of errors */ + if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0); + return status; +} + + +static void print_version (void) { + l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT); +} + + +static int getargs (lua_State *L, char **argv, int n) { + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i=n+1; i < argc; i++) + lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i=0; i < argc; i++) { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; +} + + +static int dofile (lua_State *L, const char *name) { + int status = luaL_loadfile(L, name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dostring (lua_State *L, const char *s, const char *name) { + int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1); + return report(L, status); +} + + +static int dolibrary (lua_State *L, const char *name) { + lua_getglobal(L, "require"); + lua_pushstring(L, name); + return report(L, docall(L, 1, 1)); +} + + +static const char *get_prompt (lua_State *L, int firstline) { + const char *p; + lua_getfield(L, LUA_GLOBALSINDEX, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + lua_pop(L, 1); /* remove global */ + return p; +} + + +static int incomplete (lua_State *L, int status) { + if (status == LUA_ERRSYNTAX) { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + const char *tp = msg + lmsg - (sizeof(LUA_QL("")) - 1); + if (strstr(msg, LUA_QL("")) == tp) { + lua_pop(L, 1); + return 1; + } + } + return 0; /* else... */ +} + + +static int pushline (lua_State *L, int firstline) { + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + if (lua_readline(L, b, prmt) == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ + b[l-1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; +} + + +static int loadline (lua_State *L) { + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) { /* repeat until gets a complete line */ + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(L, status)) break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; +} + + +static void dotty (lua_State *L) { + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = loadline(L)) != -1) { + if (status == 0) status = docall(L, 0, 0); + report(L, status); + if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + fputs("\n", stdout); + fflush(stdout); + progname = oldprogname; +} + + +static int handle_script (lua_State *L, char **argv, int n) { + int status; + const char *fname; + int narg = getargs(L, argv, n); /* collect arguments */ + lua_setglobal(L, "arg"); + fname = argv[n]; + if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + lua_insert(L, -(narg+1)); + if (status == 0) + status = docall(L, narg, 0); + else + lua_pop(L, narg); + return report(L, status); +} + + +/* check that argument has no extra characters at the end */ +#define notail(x) {if ((x)[2] != '\0') return -1;} + + +static int collectargs (char **argv, int *pi, int *pv, int *pe) { + int i; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) { /* option */ + case '-': + notail(argv[i]); + return (argv[i+1] != NULL ? i+1 : 0); + case '\0': + return i; + case 'i': + notail(argv[i]); + *pi = 1; /* go through */ + case 'v': + notail(argv[i]); + *pv = 1; + break; + case 'e': + *pe = 1; /* go through */ + case 'l': + if (argv[i][2] == '\0') { + i++; + if (argv[i] == NULL) return -1; + } + break; + default: return -1; /* invalid option */ + } + } + return 0; +} + + +static int runargs (lua_State *L, char **argv, int n) { + int i; + for (i = 1; i < n; i++) { + if (argv[i] == NULL) continue; + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) { /* option */ + case 'e': { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != 0) + return 1; + break; + } + case 'l': { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename)) + return 1; /* stop if file fails */ + break; + } + default: break; + } + } + return 0; +} + + +static int handle_luainit (lua_State *L) { + const char *init = getenv(LUA_INIT); + if (init == NULL) return 0; /* status OK */ + else if (init[0] == '@') + return dofile(L, init+1); + else + return dostring(L, init, "=" LUA_INIT); +} + + +struct Smain { + int argc; + char **argv; + int status; +}; + + +static int pmain (lua_State *L) { + struct Smain *s = (struct Smain *)lua_touserdata(L, 1); + char **argv = s->argv; + int script; + int has_i = 0, has_v = 0, has_e = 0; + globalL = L; + if (argv[0] && argv[0][0]) progname = argv[0]; + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + s->status = handle_luainit(L); + if (s->status != 0) return 0; + script = collectargs(argv, &has_i, &has_v, &has_e); + if (script < 0) { /* invalid args? */ + print_usage(); + s->status = 1; + return 0; + } + if (has_v) print_version(); + s->status = runargs(L, argv, (script > 0) ? script : s->argc); + if (s->status != 0) return 0; + if (script) + s->status = handle_script(L, argv, script); + if (s->status != 0) return 0; + if (has_i) + dotty(L); + else if (script == 0 && !has_e && !has_v) { + if (lua_stdin_is_tty()) { + print_version(); + dotty(L); + } + else dofile(L, NULL); /* executes stdin as a file */ + } + return 0; +} + + +int main (int argc, char **argv) { + int status; + struct Smain s; + lua_State *L = lua_open(); /* create state */ + if (L == NULL) { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + s.argc = argc; + s.argv = argv; + status = lua_cpcall(L, &pmain, &s); + report(L, status); + lua_close(L); + return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lua.def b/src/mod/legacy/languages/mod_lua/lua/lua.def new file mode 100644 index 0000000000..4ea7edc089 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lua.def @@ -0,0 +1,84 @@ +EXPORTS +lua_newstate +lua_close +lua_newthread +lua_atpanic +lua_gettop +lua_settop +lua_pushvalue +lua_remove +lua_insert +lua_replace +lua_checkstack +lua_xmove +lua_isnumber +lua_isstring +lua_iscfunction +lua_isuserdata +lua_type +lua_typename +lua_equal +lua_rawequal +lua_lessthan +lua_tonumber +lua_toboolean +lua_tolstring +lua_objlen +lua_tocfunction +lua_touserdata +lua_tothread +lua_pushnil +lua_pushnumber +lua_pushlstring +lua_pushstring +lua_pushvfstring +lua_pushfstring +lua_pushcclosure +lua_pushboolean +lua_pushlightuserdata +lua_pushthread +lua_gettable +lua_getfield +lua_rawget +lua_rawgeti +lua_createtable +lua_newuserdata +lua_getmetatable +lua_getfenv +lua_settable +lua_setfield +lua_rawset +lua_rawseti +lua_setmetatable +lua_setfenv +lua_call +lua_pcall +lua_cpcall +lua_load +lua_dump +lua_yield +lua_resume +lua_status +lua_gc +lua_error +lua_next +lua_concat +lua_getallocf +lua_setallocf +lua_setlevel +lua_getstack +lua_getinfo +lua_getlocal +lua_setlocal +lua_getupvalue +lua_setupvalue +lua_sethook +lua_gethook +lua_gethookmask +lua_gethookcount +luaL_loadbuffer +luaL_openlibs +luaL_newstate +lua_pushinteger +luaL_loadfile +luaL_loadstring \ No newline at end of file diff --git a/src/mod/legacy/languages/mod_lua/lua/lua.h b/src/mod/legacy/languages/mod_lua/lua/lua.h new file mode 100644 index 0000000000..e4bdfd3b94 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lua.h @@ -0,0 +1,388 @@ +/* +** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION "Lua 5.1" +#define LUA_RELEASE "Lua 5.1.4" +#define LUA_VERSION_NUM 501 +#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes" + + +/* mark for precompiled code (`Lua') */ +#define LUA_SIGNATURE "\033Lua" + +/* option for multiple returns in `lua_pcall' and `lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** pseudo-indices +*/ +#define LUA_REGISTRYINDEX (-10000) +#define LUA_ENVIRONINDEX (-10001) +#define LUA_GLOBALSINDEX (-10002) +#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i)) + + +/* thread status; 0 is OK */ +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + +typedef int (*lua_CFunction) (lua_State *L); + + +/* +** functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); + + +/* +** prototype for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_remove) (lua_State *L, int idx); +LUA_API void (lua_insert) (lua_State *L, int idx); +LUA_API void (lua_replace) (lua_State *L, int idx); +LUA_API int (lua_checkstack) (lua_State *L, int sz); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2); + +LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx); +LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API size_t (lua_objlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); +LUA_API void (lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API void (lua_gettable) (lua_State *L, int idx); +LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawget) (lua_State *L, int idx); +LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API void (lua_getfenv) (lua_State *L, int idx); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setfenv) (lua_State *L, int idx); + + +/* +** `load' and `call' functions (load and run Lua code) +*/ +LUA_API void (lua_call) (lua_State *L, int nargs, int nresults); +LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc); +LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yield) (lua_State *L, int nresults); +LUA_API int (lua_resume) (lua_State *L, int narg); +LUA_API int (lua_status) (lua_State *L); + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 + +LUA_API int (lua_gc) (lua_State *L, int what, int data); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); + + + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_strlen(L,i) lua_objlen(L, (i)) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) + +#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s)) +#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + + +/* +** compatibility macros and functions +*/ + +#define lua_open() luaL_newstate() + +#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX) + +#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0) + +#define lua_Chunkreader lua_Reader +#define lua_Chunkwriter lua_Writer + + +/* hack */ +LUA_API void lua_setlevel (lua_State *from, lua_State *to); + + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILRET 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debuger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar); +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n); +LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n); + +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook lua_gethook (lua_State *L); +LUA_API int lua_gethookmask (lua_State *L); +LUA_API int lua_gethookcount (lua_State *L); + + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) `global', `local', `field', `method' */ + const char *what; /* (S) `Lua', `C', `main', `tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int nups; /* (u) number of upvalues */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + int i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/luac.c b/src/mod/legacy/languages/mod_lua/lua/luac.c new file mode 100644 index 0000000000..d07017391b --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/luac.c @@ -0,0 +1,200 @@ +/* +** $Id: luac.c,v 1.54 2006/06/02 17:37:11 lhf Exp $ +** Lua compiler (saves bytecodes to files; also list bytecodes) +** See Copyright Notice in lua.h +*/ + +#include +#include +#include +#include + +#define luac_c +#define LUA_CORE + +#include "lua.h" +#include "lauxlib.h" + +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstring.h" +#include "lundump.h" + +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ + +static int listing=0; /* list bytecodes? */ +static int dumping=1; /* dump bytecodes? */ +static int stripping=0; /* strip debug information? */ +static char Output[]={ OUTPUT }; /* default output file name */ +static const char* output=Output; /* actual output file name */ +static const char* progname=PROGNAME; /* actual program name */ + +static void fatal(const char* message) +{ + fprintf(stderr,"%s: %s\n",progname,message); + exit(EXIT_FAILURE); +} + +static void cannot(const char* what) +{ + fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); + exit(EXIT_FAILURE); +} + +static void usage(const char* message) +{ + if (*message=='-') + fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); + else + fprintf(stderr,"%s: %s\n",progname,message); + fprintf(stderr, + "usage: %s [options] [filenames].\n" + "Available options are:\n" + " - process stdin\n" + " -l list\n" + " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n", + progname,Output); + exit(EXIT_FAILURE); +} + +#define IS(s) (strcmp(argv[i],s)==0) + +static int doargs(int argc, char* argv[]) +{ + int i; + int version=0; + if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; + for (i=1; itop+(i))->l.p) + +static const Proto* combine(lua_State* L, int n) +{ + if (n==1) + return toproto(L,-1); + else + { + int i,pc; + Proto* f=luaF_newproto(L); + setptvalue2s(L,L->top,f); incr_top(L); + f->source=luaS_newliteral(L,"=(" PROGNAME ")"); + f->maxstacksize=1; + pc=2*n+1; + f->code=luaM_newvector(L,pc,Instruction); + f->sizecode=pc; + f->p=luaM_newvector(L,n,Proto*); + f->sizep=n; + pc=0; + for (i=0; ip[i]=toproto(L,i-n-1); + f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); + f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); + } + f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); + return f; + } +} + +static int writer(lua_State* L, const void* p, size_t size, void* u) +{ + UNUSED(L); + return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); +} + +struct Smain { + int argc; + char** argv; +}; + +static int pmain(lua_State* L) +{ + struct Smain* s = (struct Smain*)lua_touserdata(L, 1); + int argc=s->argc; + char** argv=s->argv; + const Proto* f; + int i; + if (!lua_checkstack(L,argc)) fatal("too many input files"); + for (i=0; i1); + if (dumping) + { + FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); + if (D==NULL) cannot("open"); + lua_lock(L); + luaU_dump(L,f,writer,D,stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; +} + +int main(int argc, char* argv[]) +{ + lua_State* L; + struct Smain s; + int i=doargs(argc,argv); + argc-=i; argv+=i; + if (argc<=0) usage("no input files given"); + L=lua_open(); + if (L==NULL) fatal("not enough memory for state"); + s.argc=argc; + s.argv=argv; + if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); + lua_close(L); + return EXIT_SUCCESS; +} diff --git a/src/mod/legacy/languages/mod_lua/lua/luaconf.h b/src/mod/legacy/languages/mod_lua/lua/luaconf.h new file mode 100644 index 0000000000..ca2849b5b6 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/luaconf.h @@ -0,0 +1,766 @@ +/* +** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef lconfig_h +#define lconfig_h + +#include +#include + + +/* +** ================================================================== +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +@@ LUA_ANSI controls the use of non-ansi features. +** CHANGE it (define it) if you want Lua to avoid the use of any +** non-ansi feature or library. +*/ +#if defined(__STRICT_ANSI__) +#define LUA_ANSI +#endif + + +#if !defined(LUA_ANSI) && defined(_WIN32) +#define LUA_WIN +#endif + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#define LUA_USE_READLINE /* needs some extra libraries */ +#endif + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_DL_DYLD /* does not need extra library */ +#endif + + + +/* +@@ LUA_USE_POSIX includes all functionallity listed as X/Open System +@* Interfaces Extension (XSI). +** CHANGE it (define it) if your system is XSI compatible. +*/ +#if defined(LUA_USE_POSIX) +#define LUA_USE_MKSTEMP +#define LUA_USE_ISATTY +#define LUA_USE_POPEN +#define LUA_USE_ULONGJMP +#endif + + +/* +@@ LUA_PATH and LUA_CPATH are the names of the environment variables that +@* Lua check to set its paths. +@@ LUA_INIT is the name of the environment variable that Lua +@* checks for initialization code. +** CHANGE them if you want different names. +*/ +#define LUA_PATH "LUA_PATH" +#define LUA_CPATH "LUA_CPATH" +#define LUA_INIT "LUA_INIT" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +@* Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +@* C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ +#if defined(_WIN32) +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua" +#define LUA_CPATH_DEFAULT \ + ".\\?.dll;" ".\\?51.dll;" LUA_CDIR"?.dll;" LUA_CDIR"?51.dll;" LUA_CDIR"clibs\\?.dll;" LUA_CDIR"clibs\\?51.dll;" LUA_CDIR"loadall.dll;" LUA_CDIR"clibs\\loadall.dll" + +#else +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/5.1/" +#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" +#define LUA_PATH_DEFAULT \ + "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua" +#define LUA_CPATH_DEFAULT \ + "./?.so;" "./lib?51.so;" LUA_CDIR"?.so;" LUA_CDIR"lib?51.so;" LUA_CDIR"loadall.so" +#endif + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + + +/* +@@ LUA_PATHSEP is the character that separates templates in a path. +@@ LUA_PATH_MARK is the string that marks the substitution points in a +@* template. +@@ LUA_EXECDIR in a Windows path is replaced by the executable's +@* directory. +@@ LUA_IGMARK is a mark to ignore all before it when bulding the +@* luaopen_ function name. +** CHANGE them if for some reason your system cannot use those +** characters. (E.g., if one of those characters is a common character +** in file/directory names.) Probably you do not need to change them. +*/ +#define LUA_PATHSEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXECDIR "!" +#define LUA_IGMARK "-" + + +/* +@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. +** CHANGE that if ptrdiff_t is not adequate on your machine. (On most +** machines, ptrdiff_t gives a good choice between int or long.) +*/ +#define LUA_INTEGER ptrdiff_t + + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all standard library functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) + +#if defined(LUA_CORE) || defined(LUA_LIB) +#define LUA_API __declspec(dllexport) +#else +#define LUA_API __declspec(dllimport) +#endif + +#else + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(HAVE_VISIBILITY) && (defined(LUA_CORE) || defined(LUA_LIB)) +#define LUA_API __attribute__((visibility("default"))) +#else +#define LUA_API extern +#endif +#endif + +/* more often than not the libs go together with the core */ +#define LUALIB_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +@* exported to outside modules. +@@ LUAI_DATA is a mark for all extern (const) variables that are not to +@* be exported to outside modules. +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. +*/ +#if defined(luaall_c) +#define LUAI_FUNC static +#define LUAI_DATA /* empty */ + +#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DATA LUAI_FUNC + +#else +#define LUAI_FUNC extern +#define LUAI_DATA extern +#endif + + + +/* +@@ LUA_QL describes how error messages quote program elements. +** CHANGE it if you want a different appearance. +*/ +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +** {================================================================== +** Stand-alone configuration +** =================================================================== +*/ + +#if defined(lua_c) || defined(luaall_c) + +/* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#if defined(LUA_USE_ISATTY) +#include +#define lua_stdin_is_tty() isatty(0) +#elif defined(LUA_WIN) +#include +#include +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#else +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + +/* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*/ +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " + + +/* +@@ LUA_PROGNAME is the default name for the stand-alone Lua program. +** CHANGE it if your stand-alone interpreter has a different name and +** your system is not able to detect that name automatically. +*/ +#define LUA_PROGNAME "lua" + + +/* +@@ LUA_MAXINPUT is the maximum length for an input line in the +@* stand-alone interpreter. +** CHANGE it if you need longer lines. +*/ +#define LUA_MAXINPUT 512 + + +/* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*/ +#if defined(LUA_USE_READLINE) +#include +#include +#include +#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) +#define lua_saveline(L,idx) \ + if (lua_strlen(L,idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L,b) ((void)L, free(b)) +#else +#define lua_readline(L,b,p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L,idx) { (void)L; (void)idx; } +#define lua_freeline(L,b) { (void)L; (void)b; } +#endif + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles +@* as a percentage. +** CHANGE it if you want the GC to run faster or slower (higher values +** mean larger pauses which mean slower collection.) You can also change +** this value dynamically. +*/ +#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */ + + +/* +@@ LUAI_GCMUL defines the default speed of garbage collection relative to +@* memory allocation as a percentage. +** CHANGE it if you want to change the granularity of the garbage +** collection. (Higher values mean coarser collections. 0 represents +** infinity, where each step performs a full collection.) You can also +** change this value dynamically. +*/ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ + + + +/* +@@ LUA_COMPAT_GETN controls compatibility with old getn behavior. +** CHANGE it (define it) if you want exact compatibility with the +** behavior of setn/getn in Lua 5.0. +*/ +#undef LUA_COMPAT_GETN + +/* +@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib. +** CHANGE it to undefined as soon as you do not need a global 'loadlib' +** function (the function is still available as 'package.loadlib'). +*/ +#undef LUA_COMPAT_LOADLIB + +/* +@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature. +** CHANGE it to undefined as soon as your programs use only '...' to +** access vararg parameters (instead of the old 'arg' table). +*/ +#define LUA_COMPAT_VARARG + +/* +@@ LUA_COMPAT_MOD controls compatibility with old math.mod function. +** CHANGE it to undefined as soon as your programs use 'math.fmod' or +** the new '%' operator instead of 'math.mod'. +*/ +#define LUA_COMPAT_MOD + +/* +@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting +@* facility. +** CHANGE it to 2 if you want the old behaviour, or undefine it to turn +** off the advisory error when nesting [[...]]. +*/ +#define LUA_COMPAT_LSTR 1 + +/* +@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name. +** CHANGE it to undefined as soon as you rename 'string.gfind' to +** 'string.gmatch'. +*/ +#define LUA_COMPAT_GFIND + +/* +@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib' +@* behavior. +** CHANGE it to undefined as soon as you replace to 'luaL_register' +** your uses of 'luaL_openlib' +*/ +#define LUA_COMPAT_OPENLIB + + + +/* +@@ luai_apicheck is the assert macro used by the Lua-C API. +** CHANGE luai_apicheck if you want Lua to perform some checks in the +** parameters it gets from API calls. This may slow down the interpreter +** a bit, but may be quite useful when debugging C code that interfaces +** with Lua. A useful redefinition is to use assert.h. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(L,o) { (void)L; assert(o); } +#else +#define luai_apicheck(L,o) { (void)L; } +#endif + + +/* +@@ LUAI_BITSINT defines the number of bits in an int. +** CHANGE here if Lua cannot automatically detect the number of bits of +** your machine. Probably you do not need to change this. +*/ +/* avoid overflows in comparison */ +#if INT_MAX-20 < 32760 +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L +/* int has at least 32 bits */ +#define LUAI_BITSINT 32 +#else +#error "you must define LUA_BITSINT with number of bits in an integer" +#endif + + +/* +@@ LUAI_UINT32 is an unsigned integer with at least 32 bits. +@@ LUAI_INT32 is an signed integer with at least 32 bits. +@@ LUAI_UMEM is an unsigned integer big enough to count the total +@* memory used by Lua. +@@ LUAI_MEM is a signed integer big enough to count the total memory +@* used by Lua. +** CHANGE here if for some weird reason the default definitions are not +** good enough for your machine. (The definitions in the 'else' +** part always works, but may waste space on machines with 64-bit +** longs.) Probably you do not need to change this. +*/ +#if LUAI_BITSINT >= 32 +#define LUAI_UINT32 unsigned int +#define LUAI_INT32 int +#define LUAI_MAXINT32 INT_MAX +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else +/* 16-bit ints */ +#define LUAI_UINT32 unsigned long +#define LUAI_INT32 long +#define LUAI_MAXINT32 LONG_MAX +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif + + +/* +@@ LUAI_MAXCALLS limits the number of nested calls. +** CHANGE it if you need really deep recursive calls. This limit is +** arbitrary; its only purpose is to stop infinite recursion before +** exhausting memory. +*/ +#define LUAI_MAXCALLS 20000 + + +/* +@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function +@* can use. +** CHANGE it if you need lots of (Lua) stack space for your C +** functions. This limit is arbitrary; its only purpose is to stop C +** functions to consume unlimited stack space. (must be smaller than +** -LUA_REGISTRYINDEX) +*/ +#define LUAI_MAXCSTACK 8000 + + + +/* +** {================================================================== +** CHANGE (to smaller values) the following definitions if your system +** has a small C stack. (Or you may want to change them to larger +** values if your system has a large C stack and these limits are +** too rigid for you.) Some of these constants control the size of +** stack-allocated arrays used by the compiler or the interpreter, while +** others limit the maximum number of recursive calls that the compiler +** or the interpreter can perform. Values too large may cause a C stack +** overflow for some forms of deep constructs. +** =================================================================== +*/ + + +/* +@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and +@* syntactical nested non-terminals in a program. +*/ +#define LUAI_MAXCCALLS 200 + + +/* +@@ LUAI_MAXVARS is the maximum number of local variables per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXVARS 200 + + +/* +@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function +@* (must be smaller than 250). +*/ +#define LUAI_MAXUPVALUES 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE BUFSIZ + +/* }================================================================== */ + + + + +/* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*/ + +#define LUA_NUMBER_DOUBLE +#define LUA_NUMBER double + +/* +@@ LUAI_UACNUMBER is the result of an 'usual argument conversion' +@* over a number. +*/ +#define LUAI_UACNUMBER double + + +/* +@@ LUA_NUMBER_SCAN is the format for reading numbers. +@@ LUA_NUMBER_FMT is the format for writing numbers. +@@ lua_number2str converts a number to a string. +@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. +@@ lua_str2number converts a string to a number. +*/ +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ +#define lua_str2number(s,p) strtod((s), (p)) + + +/* +@@ The luai_num* macros define the primitive operations over numbers. +*/ +#if defined(LUA_CORE) +#include +#define luai_numadd(a,b) ((a)+(b)) +#define luai_numsub(a,b) ((a)-(b)) +#define luai_nummul(a,b) ((a)*(b)) +#define luai_numdiv(a,b) ((a)/(b)) +#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b)) +#define luai_numpow(a,b) (pow(a,b)) +#define luai_numunm(a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + +/* +@@ lua_number2int is a macro to convert lua_Number to int. +@@ lua_number2integer is a macro to convert lua_Number to lua_Integer. +** CHANGE them if you know a faster way to convert a lua_Number to +** int (with any rounding method and without throwing errors) in your +** system. In Pentium machines, a naive typecast from double to int +** in C is extremely slow, so any alternative is worth trying. +*/ + +/* On a Pentium, resort to a trick */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \ + (defined(__i386) || defined (_M_IX86) || defined(__i386__)) + +/* On a Microsoft compiler, use assembler */ +#if defined(_MSC_VER) + +#define lua_number2int(i,d) __asm fld d __asm fistp i +#define lua_number2integer(i,n) lua_number2int(i, n) + +/* the next trick should work on any Pentium, but sometimes clashes + with a DirectX idiosyncrasy */ +#else + +union luai_Cast { double l_d; long l_l; }; +#define lua_number2int(i,d) \ + { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } +#define lua_number2integer(i,n) lua_number2int(i, n) + +#endif + + +/* this option always works, but may be slow */ +#else +#define lua_number2int(i,d) ((i)=(int)(d)) +#define lua_number2integer(i,d) ((i)=(lua_Integer)(d)) + +#endif + +/* }================================================================== */ + + +/* +@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment. +** CHANGE it if your system requires alignments larger than double. (For +** instance, if your system supports long doubles and they must be +** aligned in 16-byte boundaries, then you should add long double in the +** union.) Probably you do not need to change this. +*/ +#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } + + +/* +@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling. +** CHANGE them if you prefer to use longjmp/setjmp even with C++ +** or if want/don't to use _longjmp/_setjmp instead of regular +** longjmp/setjmp. By default, Lua handles errors with exceptions when +** compiling as C++ code, with _longjmp/_setjmp when asked to use them, +** and with longjmp/setjmp otherwise. +*/ +#if defined(__cplusplus) +/* C++ exceptions */ +#define LUAI_THROW(L,c) throw(c) +#define LUAI_TRY(L,c,a) try { a } catch(...) \ + { if ((c)->status == 0) (c)->status = -1; } +#define luai_jmpbuf int /* dummy variable */ + +#elif defined(LUA_USE_ULONGJMP) +/* in Unix, try _longjmp/_setjmp (more efficient) */ +#define LUAI_THROW(L,c) _longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#else +/* default handling with long jumps */ +#define LUAI_THROW(L,c) longjmp((c)->b, 1) +#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } +#define luai_jmpbuf jmp_buf + +#endif + + +/* +@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern +@* can do during pattern-matching. +** CHANGE it if you need more captures. This limit is arbitrary. +*/ +#define LUA_MAXCAPTURES 32 + + +/* +@@ lua_tmpnam is the function that the OS library uses to create a +@* temporary name. +@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam. +** CHANGE them if you have an alternative to tmpnam (which is considered +** insecure) or if you want the original tmpnam anyway. By default, Lua +** uses tmpnam except when POSIX is available, where it uses mkstemp. +*/ +#if defined(loslib_c) || defined(luaall_c) + +#if defined(LUA_USE_MKSTEMP) +#include +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b,e) { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); } + +#else +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#endif + +#endif + + +/* +@@ lua_popen spawns a new process connected to the current one through +@* the file streams. +** CHANGE it if you have a way to implement it in your system. +*/ +#if defined(LUA_USE_POPEN) + +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) +#define lua_pclose(L,file) ((void)L, (pclose(file) != -1)) + +#elif defined(LUA_WIN) + +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) +#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1)) + +#else + +#define lua_popen(L,c,m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) +#define lua_pclose(L,file) ((void)((void)L, file), 0) + +#endif + +/* +@@ LUA_DL_* define which dynamic-library system Lua should use. +** CHANGE here if Lua has problems choosing the appropriate +** dynamic-library system for your platform (either Windows' DLL, Mac's +** dyld, or Unix's dlopen). If your system is some kind of Unix, there +** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for +** it. To use dlopen you also need to adapt the src/Makefile (probably +** adding -ldl to the linker options), so Lua does not select it +** automatically. (When you change the makefile to add -ldl, you must +** also add -DLUA_USE_DLOPEN.) +** If you do not want any kind of dynamic library, undefine all these +** options. +** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD. +*/ +#if defined(LUA_USE_DLOPEN) +#define LUA_DL_DLOPEN +#endif + +#if defined(LUA_WIN) +#define LUA_DL_DLL +#endif + + +/* +@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State +@* (the data goes just *before* the lua_State pointer). +** CHANGE (define) this if you really need that. This value must be +** a multiple of the maximum alignment required for your machine. +*/ +#define LUAI_EXTRASPACE 0 + + +/* +@@ luai_userstate* allow user-specific actions on threads. +** CHANGE them if you defined LUAI_EXTRASPACE and need to do something +** extra when a thread is created/deleted/resumed/yielded. +*/ +#define luai_userstateopen(L) ((void)L) +#define luai_userstateclose(L) ((void)L) +#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatefree(L) ((void)L) +#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateyield(L,n) ((void)L) + + +/* +@@ LUA_INTFRMLEN is the length modifier for integer conversions +@* in 'string.format'. +@@ LUA_INTFRM_T is the integer type correspoding to the previous length +@* modifier. +** CHANGE them if your system supports long long or does not support long. +*/ + +#if defined(LUA_USELONGLONG) + +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long + +#else + +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long + +#endif + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + +#endif + diff --git a/src/mod/legacy/languages/mod_lua/lua/lualib.h b/src/mod/legacy/languages/mod_lua/lua/lualib.h new file mode 100644 index 0000000000..469417f670 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lualib.h @@ -0,0 +1,53 @@ +/* +** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* Key to file-handle type */ +#define LUA_FILEHANDLE "FILE*" + + +#define LUA_COLIBNAME "coroutine" +LUALIB_API int (luaopen_base) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUALIB_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUALIB_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUALIB_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUALIB_API int (luaopen_string) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUALIB_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUALIB_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUALIB_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + + +#ifndef lua_assert +#define lua_assert(x) ((void)0) +#endif + + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lundump.c b/src/mod/legacy/languages/mod_lua/lua/lundump.c new file mode 100644 index 0000000000..8010a45795 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lundump.c @@ -0,0 +1,227 @@ +/* +** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#include + +#define lundump_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lmem.h" +#include "lobject.h" +#include "lstring.h" +#include "lundump.h" +#include "lzio.h" + +typedef struct { + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; +} LoadState; + +#ifdef LUAC_TRUST_BINARIES +#define IF(c,s) +#define error(S,s) +#else +#define IF(c,s) if (c) error(S,s) + +static void error(LoadState* S, const char* why) +{ + luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why); + luaD_throw(S->L,LUA_ERRSYNTAX); +} +#endif + +#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) +#define LoadByte(S) (lu_byte)LoadChar(S) +#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) +#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) + +static void LoadBlock(LoadState* S, void* b, size_t size) +{ + size_t r=luaZ_read(S->Z,b,size); + IF (r!=0, "unexpected end"); +} + +static int LoadChar(LoadState* S) +{ + char x; + LoadVar(S,x); + return x; +} + +static int LoadInt(LoadState* S) +{ + int x; + LoadVar(S,x); + IF (x<0, "bad integer"); + return x; +} + +static lua_Number LoadNumber(LoadState* S) +{ + lua_Number x; + LoadVar(S,x); + return x; +} + +static TString* LoadString(LoadState* S) +{ + size_t size; + LoadVar(S,size); + if (size==0) + return NULL; + else + { + char* s=luaZ_openspace(S->L,S->b,size); + LoadBlock(S,s,size); + return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ + } +} + +static void LoadCode(LoadState* S, Proto* f) +{ + int n=LoadInt(S); + f->code=luaM_newvector(S->L,n,Instruction); + f->sizecode=n; + LoadVector(S,f->code,n,sizeof(Instruction)); +} + +static Proto* LoadFunction(LoadState* S, TString* p); + +static void LoadConstants(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->k=luaM_newvector(S->L,n,TValue); + f->sizek=n; + for (i=0; ik[i]); + for (i=0; ik[i]; + int t=LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o,LoadChar(S)!=0); + break; + case LUA_TNUMBER: + setnvalue(o,LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L,o,LoadString(S)); + break; + default: + error(S,"bad constant"); + break; + } + } + n=LoadInt(S); + f->p=luaM_newvector(S->L,n,Proto*); + f->sizep=n; + for (i=0; ip[i]=NULL; + for (i=0; ip[i]=LoadFunction(S,f->source); +} + +static void LoadDebug(LoadState* S, Proto* f) +{ + int i,n; + n=LoadInt(S); + f->lineinfo=luaM_newvector(S->L,n,int); + f->sizelineinfo=n; + LoadVector(S,f->lineinfo,n,sizeof(int)); + n=LoadInt(S); + f->locvars=luaM_newvector(S->L,n,LocVar); + f->sizelocvars=n; + for (i=0; ilocvars[i].varname=NULL; + for (i=0; ilocvars[i].varname=LoadString(S); + f->locvars[i].startpc=LoadInt(S); + f->locvars[i].endpc=LoadInt(S); + } + n=LoadInt(S); + f->upvalues=luaM_newvector(S->L,n,TString*); + f->sizeupvalues=n; + for (i=0; iupvalues[i]=NULL; + for (i=0; iupvalues[i]=LoadString(S); +} + +static Proto* LoadFunction(LoadState* S, TString* p) +{ + Proto* f; + if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); + f=luaF_newproto(S->L); + setptvalue2s(S->L,S->L->top,f); incr_top(S->L); + f->source=LoadString(S); if (f->source==NULL) f->source=p; + f->linedefined=LoadInt(S); + f->lastlinedefined=LoadInt(S); + f->nups=LoadByte(S); + f->numparams=LoadByte(S); + f->is_vararg=LoadByte(S); + f->maxstacksize=LoadByte(S); + LoadCode(S,f); + LoadConstants(S,f); + LoadDebug(S,f); + IF (!luaG_checkcode(f), "bad code"); + S->L->top--; + S->L->nCcalls--; + return f; +} + +static void LoadHeader(LoadState* S) +{ + char h[LUAC_HEADERSIZE]; + char s[LUAC_HEADERSIZE]; + luaU_header(h); + LoadBlock(S,s,LUAC_HEADERSIZE); + IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header"); +} + +/* +** load precompiled chunk +*/ +Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +{ + LoadState S; + if (*name=='@' || *name=='=') + S.name=name+1; + else if (*name==LUA_SIGNATURE[0]) + S.name="binary string"; + else + S.name=name; + S.L=L; + S.Z=Z; + S.b=buff; + LoadHeader(&S); + return LoadFunction(&S,luaS_newliteral(L,"=?")); +} + +/* +* make header +*/ +void luaU_header (char* h) +{ + int x=1; + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); + h+=sizeof(LUA_SIGNATURE)-1; + *h++=(char)LUAC_VERSION; + *h++=(char)LUAC_FORMAT; + *h++=(char)*(char*)&x; /* endianness */ + *h++=(char)sizeof(int); + *h++=(char)sizeof(size_t); + *h++=(char)sizeof(Instruction); + *h++=(char)sizeof(lua_Number); + *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ +} diff --git a/src/mod/legacy/languages/mod_lua/lua/lundump.h b/src/mod/legacy/languages/mod_lua/lua/lundump.h new file mode 100644 index 0000000000..c80189dbff --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lundump.h @@ -0,0 +1,36 @@ +/* +** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "lobject.h" +#include "lzio.h" + +/* load one chunk; from lundump.c */ +LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); + +/* make header; from lundump.c */ +LUAI_FUNC void luaU_header (char* h); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); + +#ifdef luac_c +/* print one chunk; from print.c */ +LUAI_FUNC void luaU_print (const Proto* f, int full); +#endif + +/* for header of binary files -- this is Lua 5.1 */ +#define LUAC_VERSION 0x51 + +/* for header of binary files -- this is the official format */ +#define LUAC_FORMAT 0 + +/* size of header of binary files */ +#define LUAC_HEADERSIZE 12 + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lvm.c b/src/mod/legacy/languages/mod_lua/lua/lvm.c new file mode 100644 index 0000000000..ee3256ab94 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lvm.c @@ -0,0 +1,763 @@ +/* +** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + + +#include +#include +#include + +#define lvm_c +#define LUA_CORE + +#include "lua.h" + +#include "ldebug.h" +#include "ldo.h" +#include "lfunc.h" +#include "lgc.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lstate.h" +#include "lstring.h" +#include "ltable.h" +#include "ltm.h" +#include "lvm.h" + + + +/* limit for table tag-method chains (to avoid loops) */ +#define MAXTAGLOOP 100 + + +const TValue *luaV_tonumber (const TValue *obj, TValue *n) { + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { + setnvalue(n, num); + return n; + } + else + return NULL; +} + + +int luaV_tostring (lua_State *L, StkId obj) { + if (!ttisnumber(obj)) + return 0; + else { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + lua_number2str(s, n); + setsvalue2s(L, obj, luaS_new(L, s)); + return 1; + } +} + + +static void traceexec (lua_State *L, const Instruction *pc) { + lu_byte mask = L->hookmask; + const Instruction *oldpc = L->savedpc; + L->savedpc = pc; + if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { + resethookcount(L); + luaD_callhook(L, LUA_HOOKCOUNT, -1); + } + if (mask & LUA_MASKLINE) { + Proto *p = ci_func(L->ci)->l.p; + int npc = pcRel(pc, p); + int newline = getline(p, npc); + /* call linehook when enter a new function, when jump back (loop), + or when enter a new line */ + if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) + luaD_callhook(L, LUA_HOOKLINE, newline); + } +} + + +static void callTMres (lua_State *L, StkId res, const TValue *f, + const TValue *p1, const TValue *p2) { + ptrdiff_t result = savestack(L, res); + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + luaD_checkstack(L, 3); + L->top += 3; + luaD_call(L, L->top - 3, 1); + res = restorestack(L, result); + L->top--; + setobjs2s(L, res, L->top); +} + + + +static void callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3) { + setobj2s(L, L->top, f); /* push function */ + setobj2s(L, L->top+1, p1); /* 1st argument */ + setobj2s(L, L->top+2, p2); /* 2nd argument */ + setobj2s(L, L->top+3, p3); /* 3th argument */ + luaD_checkstack(L, 4); + L->top += 4; + luaD_call(L, L->top - 4, 0); +} + + +void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTMres(L, val, tm, t, key); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in gettable"); +} + + +void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) { + const TValue *tm; + if (ttistable(t)) { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ + if (!ttisnil(oldval) || /* result is no nil? */ + (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ + setobj2t(L, oldval, val); + luaC_barriert(L, h, val); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) { + callTM(L, tm, t, key, val); + return; + } + t = tm; /* else repeat with `tm' */ + } + luaG_runerror(L, "loop in settable"); +} + + +static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) { + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTMres(L, res, tm, p1, p2); + return 1; +} + + +static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, + TMS event) { + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; +} + + +static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, + TMS event) { + const TValue *tm1 = luaT_gettmbyobj(L, p1, event); + const TValue *tm2; + if (ttisnil(tm1)) return -1; /* no metamethod? */ + tm2 = luaT_gettmbyobj(L, p2, event); + if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ + return -1; + callTMres(L, L->top, tm1, p1, p2); + return !l_isfalse(L->top); +} + + +static int l_strcmp (const TString *ls, const TString *rs) { + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) { + int temp = strcoll(l, r); + if (temp != 0) return temp; + else { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; ll -= len; r += len; lr -= len; + } + } +} + + +int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numlt(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) + return res; + return luaG_ordererror(L, l, r); +} + + +static int lessequal (lua_State *L, const TValue *l, const TValue *r) { + int res; + if (ttype(l) != ttype(r)) + return luaG_ordererror(L, l, r); + else if (ttisnumber(l)) + return luai_numle(nvalue(l), nvalue(r)); + else if (ttisstring(l)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */ + return !res; + return luaG_ordererror(L, l, r); +} + + +int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { + const TValue *tm; + lua_assert(ttype(t1) == ttype(t2)); + switch (ttype(t1)) { + case LUA_TNIL: return 1; + case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); + case LUA_TUSERDATA: { + if (uvalue(t1) == uvalue(t2)) return 1; + tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, + TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: { + if (hvalue(t1) == hvalue(t2)) return 1; + tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTMres(L, L->top, tm, t1, t2); /* call TM */ + return !l_isfalse(L->top); +} + + +void luaV_concat (lua_State *L, int total, int last) { + do { + StkId top = L->base + last + 1; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { + if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) + luaG_concaterror(L, top-2, top-1); + } else if (tsvalue(top-1)->len == 0) /* second op is empty? */ + (void)tostring(L, top - 2); /* result is first op (as string) */ + else { + /* at least two string values; get as many as possible */ + size_t tl = tsvalue(top-1)->len; + char *buffer; + int i; + /* collect total length */ + for (n = 1; n < total && tostring(L, top-n-1); n++) { + size_t l = tsvalue(top-n-1)->len; + if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + for (i=n; i>0; i--) { /* concat all strings */ + size_t l = tsvalue(top-i)->len; + memcpy(buffer+tl, svalue(top-i), l); + tl += l; + } + setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); + } + total -= n-1; /* got `n' strings to create 1 new */ + last -= n-1; + } while (total > 1); /* repeat until only 1 result left */ +} + + +static void Arith (lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) { + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) { + lua_Number nb = nvalue(b), nc = nvalue(c); + switch (op) { + case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break; + case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break; + case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break; + case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break; + case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break; + case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break; + case TM_UNM: setnvalue(ra, luai_numunm(nb)); break; + default: lua_assert(0); break; + } + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); +} + + + +/* +** some macros for common tasks in `luaV_execute' +*/ + +#define runtime_check(L, c) { if (!(c)) break; } + +#define RA(i) (base+GETARG_A(i)) +/* to be used after possible stack reallocation */ +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) +#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) + + +#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} + + +#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } + + +#define arith_op(op,tm) { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(nb, nc)); \ + } \ + else \ + Protect(Arith(L, ra, rb, rc, tm)); \ + } + + + +void luaV_execute (lua_State *L, int nexeccalls) { + LClosure *cl; + StkId base; + TValue *k; + const Instruction *pc; + reentry: /* entry point */ + lua_assert(isLua(L->ci)); + pc = L->savedpc; + cl = &clvalue(L->ci->func)->l; + base = L->base; + k = cl->p->k; + /* main loop of interpreter */ + for (;;) { + const Instruction i = *pc++; + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { + traceexec(L, pc); + if (L->status == LUA_YIELD) { /* did hook yield? */ + L->savedpc = pc - 1; + return; + } + base = L->base; + } + /* warning!! several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == L->base && L->base == L->ci->base); + lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); + lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); + switch (GET_OPCODE(i)) { + case OP_MOVE: { + setobjs2s(L, ra, RB(i)); + continue; + } + case OP_LOADK: { + setobj2s(L, ra, KBx(i)); + continue; + } + case OP_LOADBOOL: { + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ + continue; + } + case OP_LOADNIL: { + TValue *rb = RB(i); + do { + setnilvalue(rb--); + } while (rb >= ra); + continue; + } + case OP_GETUPVAL: { + int b = GETARG_B(i); + setobj2s(L, ra, cl->upvals[b]->v); + continue; + } + case OP_GETGLOBAL: { + TValue g; + TValue *rb = KBx(i); + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(rb)); + Protect(luaV_gettable(L, &g, rb, ra)); + continue; + } + case OP_GETTABLE: { + Protect(luaV_gettable(L, RB(i), RKC(i), ra)); + continue; + } + case OP_SETGLOBAL: { + TValue g; + sethvalue(L, &g, cl->env); + lua_assert(ttisstring(KBx(i))); + Protect(luaV_settable(L, &g, KBx(i), ra)); + continue; + } + case OP_SETUPVAL: { + UpVal *uv = cl->upvals[GETARG_B(i)]; + setobj(L, uv->v, ra); + luaC_barrier(L, uv, ra); + continue; + } + case OP_SETTABLE: { + Protect(luaV_settable(L, ra, RKB(i), RKC(i))); + continue; + } + case OP_NEWTABLE: { + int b = GETARG_B(i); + int c = GETARG_C(i); + sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c))); + Protect(luaC_checkGC(L)); + continue; + } + case OP_SELF: { + StkId rb = RB(i); + setobjs2s(L, ra+1, rb); + Protect(luaV_gettable(L, rb, RKC(i), ra)); + continue; + } + case OP_ADD: { + arith_op(luai_numadd, TM_ADD); + continue; + } + case OP_SUB: { + arith_op(luai_numsub, TM_SUB); + continue; + } + case OP_MUL: { + arith_op(luai_nummul, TM_MUL); + continue; + } + case OP_DIV: { + arith_op(luai_numdiv, TM_DIV); + continue; + } + case OP_MOD: { + arith_op(luai_nummod, TM_MOD); + continue; + } + case OP_POW: { + arith_op(luai_numpow, TM_POW); + continue; + } + case OP_UNM: { + TValue *rb = RB(i); + if (ttisnumber(rb)) { + lua_Number nb = nvalue(rb); + setnvalue(ra, luai_numunm(nb)); + } + else { + Protect(Arith(L, ra, rb, rb, TM_UNM)); + } + continue; + } + case OP_NOT: { + int res = l_isfalse(RB(i)); /* next assignment may change this value */ + setbvalue(ra, res); + continue; + } + case OP_LEN: { + const TValue *rb = RB(i); + switch (ttype(rb)) { + case LUA_TTABLE: { + setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); + break; + } + case LUA_TSTRING: { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + break; + } + default: { /* try metamethod */ + Protect( + if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN)) + luaG_typeerror(L, rb, "get length of"); + ) + } + } + continue; + } + case OP_CONCAT: { + int b = GETARG_B(i); + int c = GETARG_C(i); + Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L)); + setobjs2s(L, RA(i), base+b); + continue; + } + case OP_JMP: { + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_EQ: { + TValue *rb = RKB(i); + TValue *rc = RKC(i); + Protect( + if (equalobj(L, rb, rc) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LT: { + Protect( + if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_LE: { + Protect( + if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) + dojump(L, pc, GETARG_sBx(*pc)); + ) + pc++; + continue; + } + case OP_TEST: { + if (l_isfalse(ra) != GETARG_C(i)) + dojump(L, pc, GETARG_sBx(*pc)); + pc++; + continue; + } + case OP_TESTSET: { + TValue *rb = RB(i); + if (l_isfalse(rb) != GETARG_C(i)) { + setobjs2s(L, ra, rb); + dojump(L, pc, GETARG_sBx(*pc)); + } + pc++; + continue; + } + case OP_CALL: { + int b = GETARG_B(i); + int nresults = GETARG_C(i) - 1; + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + switch (luaD_precall(L, ra, nresults)) { + case PCRLUA: { + nexeccalls++; + goto reentry; /* restart luaV_execute over new Lua function */ + } + case PCRC: { + /* it was a C function (`precall' called it); adjust results */ + if (nresults >= 0) L->top = L->ci->top; + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_TAILCALL: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b; /* else previous instruction set top */ + L->savedpc = pc; + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); + switch (luaD_precall(L, ra, LUA_MULTRET)) { + case PCRLUA: { + /* tail call: put new frame in place of previous one */ + CallInfo *ci = L->ci - 1; /* previous frame */ + int aux; + StkId func = ci->func; + StkId pfunc = (ci+1)->func; /* previous function index */ + if (L->openupval) luaF_close(L, ci->base); + L->base = ci->base = ci->func + ((ci+1)->base - pfunc); + for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ + setobjs2s(L, func+aux, pfunc+aux); + ci->top = L->top = func+aux; /* correct top */ + lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); + ci->savedpc = L->savedpc; + ci->tailcalls++; /* one more call lost */ + L->ci--; /* remove new frame */ + goto reentry; + } + case PCRC: { /* it was a C function (`precall' called it) */ + base = L->base; + continue; + } + default: { + return; /* yield */ + } + } + } + case OP_RETURN: { + int b = GETARG_B(i); + if (b != 0) L->top = ra+b-1; + if (L->openupval) luaF_close(L, base); + L->savedpc = pc; + b = luaD_poscall(L, ra); + if (--nexeccalls == 0) /* was previous function running `here'? */ + return; /* no: return */ + else { /* yes: continue its execution */ + if (b) L->top = L->ci->top; + lua_assert(isLua(L->ci)); + lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); + goto reentry; + } + } + case OP_FORLOOP: { + lua_Number step = nvalue(ra+2); + lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra+1); + if (luai_numlt(0, step) ? luai_numle(idx, limit) + : luai_numle(limit, idx)) { + dojump(L, pc, GETARG_sBx(i)); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra+3, idx); /* ...and external index */ + } + continue; + } + case OP_FORPREP: { + const TValue *init = ra; + const TValue *plimit = ra+1; + const TValue *pstep = ra+2; + L->savedpc = pc; /* next steps may throw errors */ + if (!tonumber(init, ra)) + luaG_runerror(L, LUA_QL("for") " initial value must be a number"); + else if (!tonumber(plimit, ra+1)) + luaG_runerror(L, LUA_QL("for") " limit must be a number"); + else if (!tonumber(pstep, ra+2)) + luaG_runerror(L, LUA_QL("for") " step must be a number"); + setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); + dojump(L, pc, GETARG_sBx(i)); + continue; + } + case OP_TFORLOOP: { + StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb+2, ra+2); + setobjs2s(L, cb+1, ra+1); + setobjs2s(L, cb, ra); + L->top = cb+3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i))); + L->top = L->ci->top; + cb = RA(i) + 3; /* previous call may change the stack */ + if (!ttisnil(cb)) { /* continue loop? */ + setobjs2s(L, cb-1, cb); /* save control variable */ + dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ + } + pc++; + continue; + } + case OP_SETLIST: { + int n = GETARG_B(i); + int c = GETARG_C(i); + int last; + Table *h; + if (n == 0) { + n = cast_int(L->top - ra) - 1; + L->top = L->ci->top; + } + if (c == 0) c = cast_int(*pc++); + runtime_check(L, ttistable(ra)); + h = hvalue(ra); + last = ((c-1)*LFIELDS_PER_FLUSH) + n; + if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-alloc it at once */ + for (; n > 0; n--) { + TValue *val = ra+n; + setobj2t(L, luaH_setnum(L, h, last--), val); + luaC_barriert(L, h, val); + } + continue; + } + case OP_CLOSE: { + luaF_close(L, ra); + continue; + } + case OP_CLOSURE: { + Proto *p; + Closure *ncl; + int nup, j; + p = cl->p->p[GETARG_Bx(i)]; + nup = p->nups; + ncl = luaF_newLclosure(L, nup, cl->env); + ncl->l.p = p; + for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)]; + else { + lua_assert(GET_OPCODE(*pc) == OP_MOVE); + ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); + } + } + setclvalue(L, ra, ncl); + Protect(luaC_checkGC(L)); + continue; + } + case OP_VARARG: { + int b = GETARG_B(i) - 1; + int j; + CallInfo *ci = L->ci; + int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; + if (b == LUA_MULTRET) { + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + b = n; + L->top = ra + n; + } + for (j = 0; j < b; j++) { + if (j < n) { + setobjs2s(L, ra + j, ci->base - n + j); + } + else { + setnilvalue(ra + j); + } + } + continue; + } + } + } +} + diff --git a/src/mod/legacy/languages/mod_lua/lua/lvm.h b/src/mod/legacy/languages/mod_lua/lua/lvm.h new file mode 100644 index 0000000000..bfe4f5678d --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lvm.h @@ -0,0 +1,36 @@ +/* +** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o))) + +#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \ + (((o) = luaV_tonumber(o,n)) != NULL)) + +#define equalobj(L,o1,o2) \ + (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2)) + + +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls); +LUAI_FUNC void luaV_concat (lua_State *L, int total, int last); + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/lzio.c b/src/mod/legacy/languages/mod_lua/lua/lzio.c new file mode 100644 index 0000000000..293edd59b0 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lzio.c @@ -0,0 +1,82 @@ +/* +** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $ +** a generic input stream interface +** See Copyright Notice in lua.h +*/ + + +#include + +#define lzio_c +#define LUA_CORE + +#include "lua.h" + +#include "llimits.h" +#include "lmem.h" +#include "lstate.h" +#include "lzio.h" + + +int luaZ_fill (ZIO *z) { + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) return EOZ; + z->n = size - 1; + z->p = buff; + return char2int(*(z->p++)); +} + + +int luaZ_lookahead (ZIO *z) { + if (z->n == 0) { + if (luaZ_fill(z) == EOZ) + return EOZ; + else { + z->n++; /* luaZ_fill removed first byte; put back it */ + z->p--; + } + } + return char2int(*z->p); +} + + +void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; +} + + +/* --------------------------------------------------------------- read --- */ +size_t luaZ_read (ZIO *z, void *b, size_t n) { + while (n) { + size_t m; + if (luaZ_lookahead(z) == EOZ) + return n; /* return number of missing bytes */ + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ +char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { + if (n > buff->buffsize) { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; +} + + diff --git a/src/mod/legacy/languages/mod_lua/lua/lzio.h b/src/mod/legacy/languages/mod_lua/lua/lzio.h new file mode 100644 index 0000000000..51d695d8c1 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/lzio.h @@ -0,0 +1,67 @@ +/* +** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define char2int(c) cast(int, cast(unsigned char, (c))) + +#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z)) + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ +LUAI_FUNC int luaZ_lookahead (ZIO *z); + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; + void* data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/src/mod/legacy/languages/mod_lua/lua/print.c b/src/mod/legacy/languages/mod_lua/lua/print.c new file mode 100644 index 0000000000..e240cfc3c6 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/lua/print.c @@ -0,0 +1,227 @@ +/* +** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $ +** print bytecodes +** See Copyright Notice in lua.h +*/ + +#include +#include + +#define luac_c +#define LUA_CORE + +#include "ldebug.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lundump.h" + +#define PrintFunction luaU_print + +#define Sizeof(x) ((int)sizeof(x)) +#define VOID(p) ((const void*)(p)) + +static void PrintString(const TString* ts) +{ + const char* s=getstr(ts); + size_t i,n=ts->tsv.len; + putchar('"'); + for (i=0; ik[i]; + switch (ttype(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT,nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d",ttype(o)); + break; + } +} + +static void PrintCode(const Proto* f) +{ + const Instruction* code=f->code; + int pc,n=f->sizecode; + for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); + printf("%-9s\t",luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d",a); + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); + break; + case iABx: + if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); + break; + case iAsBx: + if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); PrintConstant(f,bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-"); + break; + case OP_GETGLOBAL: + case OP_SETGLOBAL: + printf("\t; %s",svalue(&f->k[bx])); + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); + printf(" "); + if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + printf("\t; to %d",sbx+pc+2); + break; + case OP_CLOSURE: + printf("\t; %p",VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c==0) printf("\t; %d",(int)code[++pc]); + else printf("\t; %d",c); + break; + default: + break; + } + printf("\n"); + } +} + +#define SS(x) (x==1)?"":"s" +#define S(x) x,SS(x) + +static void PrintHeader(const Proto* f) +{ + const char* s=getstr(f->source); + if (*s=='@' || *s=='=') + s++; + else if (*s==LUA_SIGNATURE[0]) + s="(bstring)"; + else + s="(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n", + (f->linedefined==0)?"main":"function",s, + f->linedefined,f->lastlinedefined, + S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + f->numparams,f->is_vararg?"+":"",SS(f->numparams), + S(f->maxstacksize),S(f->nups)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars),S(f->sizek),S(f->sizep)); +} + +static void PrintConstants(const Proto* f) +{ + int i,n=f->sizek; + printf("constants (%d) for %p:\n",n,VOID(f)); + for (i=0; isizelocvars; + printf("locals (%d) for %p:\n",n,VOID(f)); + for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); + } +} + +static void PrintUpvalues(const Proto* f) +{ + int i,n=f->sizeupvalues; + printf("upvalues (%d) for %p:\n",n,VOID(f)); + if (f->upvalues==NULL) return; + for (i=0; iupvalues[i])); + } +} + +void PrintFunction(const Proto* f, int full) +{ + int i,n=f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) + { + PrintConstants(f); + PrintLocals(f); + PrintUpvalues(f); + } + for (i=0; ip[i],full); +} diff --git a/src/mod/legacy/languages/mod_lua/mod_lua.2008.vcproj b/src/mod/legacy/languages/mod_lua/mod_lua.2008.vcproj new file mode 100644 index 0000000000..6604a9bbf8 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/mod_lua.2008.vcproj @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/legacy/languages/mod_lua/mod_lua.2010.vcxproj b/src/mod/legacy/languages/mod_lua/mod_lua.2010.vcxproj new file mode 100644 index 0000000000..7bab01a7ff --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/mod_lua.2010.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_lua + {7B077E7F-1BE7-4291-AB86-55E527B25CAC} + mod_lua + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + .;./lua;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + false + + + false + + + + + + + X64 + + + .;./lua;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + false + + + false + + + MachineX64 + + + + + .;./lua;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + + + false + + + + + + + X64 + + + .;./lua;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + + + false + + + MachineX64 + + + + + + + 6385;%(DisableSpecificWarnings) + 6385;%(DisableSpecificWarnings) + 6385;%(DisableSpecificWarnings) + 6385;%(DisableSpecificWarnings) + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + {d0b36172-cd76-454a-9b89-990025266c2a} + false + + + + + + \ No newline at end of file diff --git a/src/mod/legacy/languages/mod_lua/mod_lua.2012.vcxproj b/src/mod/legacy/languages/mod_lua/mod_lua.2012.vcxproj new file mode 100644 index 0000000000..c1261f9167 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/mod_lua.2012.vcxproj @@ -0,0 +1,160 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + mod_lua + {7B077E7F-1BE7-4291-AB86-55E527B25CAC} + mod_lua + Win32Proj + + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + DynamicLibrary + MultiByte + v110 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + + + + .;./lua;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + false + + + false + + + + + + + X64 + + + .;./lua;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + false + + + false + + + MachineX64 + + + + + .;./lua;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + + + false + + + + + + + X64 + + + .;./lua;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_WIN32;%(PreprocessorDefinitions) + + + 4127; 4505;%(DisableSpecificWarnings) + + + false + + + MachineX64 + + + + + + + 6385;%(DisableSpecificWarnings) + 6385;%(DisableSpecificWarnings) + 6385;%(DisableSpecificWarnings) + 6385;%(DisableSpecificWarnings) + + + + + {202d7a4e-760d-4d0e-afa1-d7459ced30ff} + false + + + {d0b36172-cd76-454a-9b89-990025266c2a} + false + + + + + + diff --git a/src/mod/legacy/languages/mod_lua/mod_lua.cpp b/src/mod/legacy/languages/mod_lua/mod_lua.cpp new file mode 100644 index 0000000000..9715f0dc74 --- /dev/null +++ b/src/mod/legacy/languages/mod_lua/mod_lua.cpp @@ -0,0 +1,713 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2012, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * mod_lua.c -- Lua + * + */ + + + +#include +#include +SWITCH_BEGIN_EXTERN_C +#include "lua.h" +#include +#include +#include "mod_lua_extra.h" +SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_lua_shutdown); + +SWITCH_MODULE_DEFINITION_EX(mod_lua, mod_lua_load, mod_lua_shutdown, NULL, SMODF_GLOBAL_SYMBOLS); +static struct { + switch_memory_pool_t *pool; + char *xml_handler; +} globals; + +int luaopen_freeswitch(lua_State * L); +int lua_thread(const char *text); + +static int panic(lua_State * L) +{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)); + + return 0; +} + +static void lua_uninit(lua_State * L) +{ + lua_gc(L, LUA_GCCOLLECT, 0); + lua_close(L); +} + +static int traceback(lua_State * L) +{ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; +} + +int docall(lua_State * L, int narg, int nresults, int perror) +{ + int status; + int base = lua_gettop(L) - narg; /* function index */ + + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + + status = lua_pcall(L, narg, nresults, base); + + lua_remove(L, base); /* remove traceback function */ + /* force a complete garbage collection in case of errors */ + if (status != 0) { + lua_gc(L, LUA_GCCOLLECT, 0); + } + + if (status && perror) { + const char *err = lua_tostring(L, -1); + if (!zstr(err)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err); + } + //lua_pop(L, 1); /* pop error message from the stack */ + // pass error up to top + lua_error(L); + } + + return status; +} + + +static lua_State *lua_init(void) +{ + lua_State *L = lua_open(); + int error = 0; + + if (L) { + const char *buff = "os.exit = function() freeswitch.consoleLog(\"err\", \"Surely you jest! exiting is a bad plan....\\n\") end"; + lua_gc(L, LUA_GCSTOP, 0); + luaL_openlibs(L); + luaopen_freeswitch(L); + lua_gc(L, LUA_GCRESTART, 0); + lua_atpanic(L, panic); + error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0); + } + return L; +} + + +static int lua_parse_and_execute(lua_State * L, char *input_code) +{ + int error = 0; + + if (zstr(input_code)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No code to execute!\n"); + return 1; + } + + while(input_code && (*input_code == ' ' || *input_code == '\n' || *input_code == '\r')) input_code++; + + if (*input_code == '~') { + char *buff = input_code + 1; + error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0); //lua_pcall(L, 0, 0, 0); + } else if (!strncasecmp(input_code, "#!/lua", 6)) { + char *buff = input_code + 6; + error = luaL_loadbuffer(L, buff, strlen(buff), "line") || docall(L, 0, 0, 0); //lua_pcall(L, 0, 0, 0); + } else { + char *args = strchr(input_code, ' '); + if (args) { + char *code = NULL; + int x, argc; + char *argv[128] = { 0 }; + *args++ = '\0'; + + if ((argc = switch_separate_string(args, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { + switch_stream_handle_t stream = { 0 }; + SWITCH_STANDARD_STREAM(stream); + + stream.write_function(&stream, " argv = {[0]='%y', ", input_code); + for (x = 0; x < argc; x++) { + stream.write_function(&stream, "'%y'%s", argv[x], x == argc - 1 ? "" : ", "); + } + stream.write_function(&stream, " };"); + code = (char *) stream.data; + } else { + code = switch_mprintf("argv = {[0]='%s'};", input_code); + } + + if (code) { + error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0); + switch_safe_free(code); + } + } else { + // Force empty argv table + char *code = NULL; + code = switch_mprintf("argv = {[0]='%s'};", input_code); + error = luaL_loadbuffer(L, code, strlen(code), "line") || docall(L, 0, 0, 0); + switch_safe_free(code); + } + + if (!error) { + char *file = input_code, *fdup = NULL; + + if (!switch_is_file_path(file)) { + fdup = switch_mprintf("%s/%s", SWITCH_GLOBAL_dirs.script_dir, file); + switch_assert(fdup); + file = fdup; + } + error = luaL_loadfile(L, file) || docall(L, 0, 0, 0); + switch_safe_free(fdup); + } + } + + if (error) { + const char *err = lua_tostring(L, -1); + if (!zstr(err)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err); + } + lua_pop(L, 1); /* pop error message from the stack */ + } + + return error; +} + +struct lua_thread_helper { + switch_memory_pool_t *pool; + char *input_code; +}; + +static void *SWITCH_THREAD_FUNC lua_thread_run(switch_thread_t *thread, void *obj) +{ + struct lua_thread_helper *lth = (struct lua_thread_helper *) obj; + switch_memory_pool_t *pool = lth->pool; + lua_State *L = lua_init(); /* opens Lua */ + + lua_parse_and_execute(L, lth->input_code); + + lth = NULL; + + switch_core_destroy_memory_pool(&pool); + + lua_uninit(L); + + return NULL; +} + + +static switch_xml_t lua_fetch(const char *section, + const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data) +{ + + switch_xml_t xml = NULL; + + if (!zstr(globals.xml_handler)) { + lua_State *L = lua_init(); + char *mycmd = strdup(globals.xml_handler); + const char *str; + int error; + + switch_assert(mycmd); + + lua_newtable(L); + + lua_pushstring(L, "section"); + lua_pushstring(L, switch_str_nil(section)); + lua_rawset(L, -3); + lua_pushstring(L, "tag_name"); + lua_pushstring(L, switch_str_nil(tag_name)); + lua_rawset(L, -3); + lua_pushstring(L, "key_name"); + lua_pushstring(L, switch_str_nil(key_name)); + lua_rawset(L, -3); + lua_pushstring(L, "key_value"); + lua_pushstring(L, switch_str_nil(key_value)); + lua_rawset(L, -3); + lua_setglobal(L, "XML_REQUEST"); + + if (params) { + mod_lua_conjure_event(L, params, "params", 1); + } + + if((error = lua_parse_and_execute(L, mycmd))){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "LUA script parse/execute error!\n"); + return NULL; + } + + lua_getfield(L, LUA_GLOBALSINDEX, "XML_STRING"); + str = lua_tostring(L, 1); + + if (str) { + if (zstr(str)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Result\n"); + } else if (!(xml = switch_xml_parse_str_dynamic((char *)str, SWITCH_TRUE))) { + /* const char -> char conversion was OK because switch_xml_parse_str_dynamic makes a duplicate of str + and saves this duplcate as root->m which is freed when switch_xml_free is issued + */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing XML Result!\n"); + } + } + + lua_uninit(L); + free(mycmd); + } + + return xml; +} + + +static void lua_event_handler(switch_event_t *event); + +static switch_status_t do_config(void) +{ + const char *cf = "lua.conf"; + switch_xml_t cfg, xml, settings, param, hook; + switch_stream_handle_t path_stream = {0}; + switch_stream_handle_t cpath_stream = {0}; + + if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); + return SWITCH_STATUS_TERM; + } + + SWITCH_STANDARD_STREAM(path_stream); + SWITCH_STANDARD_STREAM(cpath_stream); + if ((settings = switch_xml_child(cfg, "settings"))) { + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + + if (!strcmp(var, "xml-handler-script")) { + globals.xml_handler = switch_core_strdup(globals.pool, val); + } else if (!strcmp(var, "xml-handler-bindings")) { + if (!zstr(globals.xml_handler)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "binding '%s' to '%s'\n", globals.xml_handler, val); + switch_xml_bind_search_function(lua_fetch, switch_xml_parse_section_string(val), NULL); + } + } else if (!strcmp(var, "module-directory") && !zstr(val)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: appending module directory: '%s'\n", val); + if (cpath_stream.data_len) { + cpath_stream.write_function(&cpath_stream, ";"); + } + cpath_stream.write_function(&cpath_stream, "%s", val); + } else if (!strcmp(var, "script-directory") && !zstr(val)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: appending script directory: '%s'\n", val); + if (path_stream.data_len) { + path_stream.write_function(&path_stream, ";"); + } + path_stream.write_function(&path_stream, "%s", val); + } + } + + for (hook = switch_xml_child(settings, "hook"); hook; hook = hook->next) { + char *event = (char *) switch_xml_attr_soft(hook, "event"); + char *subclass = (char *) switch_xml_attr_soft(hook, "subclass"); + //char *script = strdup( (char *) switch_xml_attr_soft(hook, "script")); + char *script = (char *) switch_xml_attr_soft(hook, "script"); + switch_event_types_t evtype; + + if (!zstr(script)) { + script = switch_core_strdup(globals.pool, script); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "hook params: '%s' | '%s' | '%s'\n", event, subclass, script); + + if (switch_name_event(event,&evtype) == SWITCH_STATUS_SUCCESS) { + if (!zstr(script)) { + if (switch_event_bind(modname, evtype, !zstr(subclass) ? subclass : SWITCH_EVENT_SUBCLASS_ANY, + lua_event_handler, script) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "event handler for '%s' set to '%s'\n", switch_event_name(evtype), script); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot set event handler: unsuccessful bind\n"); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot set event handler: no script name for event type '%s'\n", event); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot set event handler: unknown event type '%s'\n", event); + } + } + } + + if (cpath_stream.data_len) { + char *lua_cpath = NULL; + if ((lua_cpath = getenv("LUA_CPATH"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: appending LUA_CPATH: '%s'\n", lua_cpath); + cpath_stream.write_function(&cpath_stream, ";%s", lua_cpath); + } +#ifdef WIN32 + if (_putenv_s("LUA_CPATH", (char *)cpath_stream.data) != 0) { +#else + if (setenv("LUA_CPATH", (char *)cpath_stream.data, 1) == ENOMEM) { +#endif + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: LUA_CPATH unable to be set, out of memory: '%s'\n", (char *)cpath_stream.data); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: LUA_CPATH set to: '%s'\n", (char *)cpath_stream.data); + } + } + switch_safe_free(cpath_stream.data); + + if (path_stream.data_len) { + char *lua_path = NULL; + if ((lua_path = getenv("LUA_PATH"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: appending LUA_PATH: '%s'\n", lua_path); + path_stream.write_function(&path_stream, ";%s", lua_path); + } +#ifdef WIN32 + if (_putenv_s("LUA_PATH", (char *)path_stream.data) != 0) { +#else + if (setenv("LUA_PATH", (char *)path_stream.data, 1) == ENOMEM) { +#endif + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: LUA_PATH unable to be set, out of memory: '%s'\n", (char *)path_stream.data); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "lua: LUA_PATH set to: '%s'\n", (char *)path_stream.data); + } + } + + if ((settings = switch_xml_child(cfg, "settings"))) { + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + if (!strcmp(var, "startup-script")) { + if (val) { + lua_thread(val); + /* wait 10ms to avoid lua init issues */ + switch_yield(10000); + } + } + } + } + + switch_safe_free(path_stream.data); + + switch_xml_free(xml); + + return SWITCH_STATUS_SUCCESS; +} + +int lua_thread(const char *text) +{ + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; + switch_memory_pool_t *pool; + lua_thread_helper *lth; + + switch_core_new_memory_pool(&pool); + lth = (lua_thread_helper *) switch_core_alloc(pool, sizeof(*lth)); + lth->pool = pool; + lth->input_code = switch_core_strdup(lth->pool, text); + + switch_threadattr_create(&thd_attr, lth->pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&thread, thd_attr, lua_thread_run, lth, lth->pool); + + return 0; +} + +static void lua_event_handler(switch_event_t *event) +{ + lua_State *L = lua_init(); + char *script = NULL; + + if (event->bind_user_data) { + script = strdup((char *)event->bind_user_data); + } + + mod_lua_conjure_event(L, event, "event", 1); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "lua event hook: execute '%s'\n", (char *)script); + lua_parse_and_execute(L, (char *)script); + lua_uninit(L); + + switch_safe_free(script); +} + +SWITCH_STANDARD_APP(lua_function) +{ + lua_State *L = lua_init(); + char *mycmd; + + if (zstr(data)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no args specified!\n"); + return; + } + + mod_lua_conjure_session(L, session, "session", 1); + + mycmd = strdup((char *) data); + switch_assert(mycmd); + + lua_parse_and_execute(L, mycmd); + lua_uninit(L); + free(mycmd); + +} + +SWITCH_STANDARD_API(luarun_api_function) +{ + + if (zstr(cmd)) { + stream->write_function(stream, "-ERR no args specified!\n"); + } else { + lua_thread(cmd); + stream->write_function(stream, "+OK\n"); + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_STANDARD_CHAT_APP(lua_chat_function) +{ + lua_State *L = lua_init(); + char *dup = NULL; + + if (data) { + dup = strdup(data); + } + + mod_lua_conjure_event(L, message, "message", 1); + lua_parse_and_execute(L, (char *)dup); + lua_uninit(L); + + switch_safe_free(dup); + + return SWITCH_STATUS_SUCCESS; + +} + +SWITCH_STANDARD_API(lua_api_function) +{ + + lua_State *L = lua_init(); + char *mycmd; + int error; + + if (zstr(cmd)) { + stream->write_function(stream, ""); + } else { + + mycmd = strdup(cmd); + switch_assert(mycmd); + + if (session) { + mod_lua_conjure_session(L, session, "session", 1); + } + + mod_lua_conjure_stream(L, stream, "stream", 1); + + if (stream->param_event) { + mod_lua_conjure_event(L, stream->param_event, "env", 1); + } + + if ((error = lua_parse_and_execute(L, mycmd))) { + char * http = switch_event_get_header(stream->param_event, "http-uri"); + if (http && (!strncasecmp(http, "/api/", 5) || !strncasecmp(http, "/webapi/", 8))) { + /* api -> fs api streams the Content-Type e.g. text/html or text/xml */ + /* api -> default Content-Type is text/plain */ + /* webapi, txtapi -> Content-Type defined in mod_xmlrpc text/html resp. text/plain */ + stream->write_function(stream, "

Error Executing Script

"); + } else { + stream->write_function(stream, "-ERR Cannot execute script\n"); + } + } + lua_uninit(L); + free(mycmd); + } + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_STANDARD_DIALPLAN(lua_dialplan_hunt) +{ + lua_State *L = lua_init(); + switch_caller_extension_t *extension = NULL; + switch_channel_t *channel = switch_core_session_get_channel(session); + char *cmd = NULL; + + if (!caller_profile) { + if (!(caller_profile = switch_channel_get_caller_profile(channel))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Obtaining Profile!\n"); + goto done; + } + } + + if (!caller_profile->context) { + caller_profile->context = "lua/dialplan.lua"; + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Processing %s->%s in context/script %s\n", + caller_profile->caller_id_name, caller_profile->destination_number, caller_profile->context); + + if ((extension = switch_caller_extension_new(session, "_anon_", caller_profile->destination_number)) == 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); + goto done; + } + + cmd = strdup(caller_profile->context); + switch_assert(cmd); + + mod_lua_conjure_session(L, session, "session", 1); + lua_parse_and_execute(L, cmd); + + /* expecting ACTIONS = { {"app1", "app_data1"}, { "app2" }, "app3" } -- each of three is valid */ + lua_getfield(L, LUA_GLOBALSINDEX, "ACTIONS"); + if (!lua_istable(L, 1)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + "Global variable ACTIONS may only be a table\n"); + goto done; + } + + lua_pushnil(L); /* STACK = tab | nil */ + + while (lua_next(L, 1) != 0) { /* STACK = tab | k1 .. kn | vn */ + char *application = NULL, *app_data = NULL; + + if (lua_isstring(L, -1)) { + application = strdup(lua_tostring(L, -1)); + app_data = strdup(""); + + } else if (lua_istable(L, -1)) { + int i = lua_gettop(L); + + lua_pushnil(L); /* STACK = tab1 | k1 .. kn | tab2 | nil */ + + if (lua_next(L, i) != 0) { /* STACK = tab1 | k1 .. kn | tab2 | k | v */ + + if (!lua_isstring(L, -1)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + "First element in each table in the ACTIONS table may only be a string - application name\n"); + goto rollback; + } + + application = strdup(lua_tostring(L, -1)); + + lua_pop(L, 1); + + if (lua_next(L, i) == 0) { /* STACK = tab1 | k1 .. kn | tab2 | k | k | v */ + app_data = strdup(""); + + } else { + if (!lua_isstring(L, -1)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + "Second (optional) element in each table in the ACTIONS table may only be a string - app_data\n"); + free(application); + goto rollback; + } + app_data = strdup(lua_tostring(L, -1)); + } + + } + + lua_settop(L, i); /* STACK = tab1 | k1 .. kn | tab2 */ + + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + "ACTIONS table may only contain strings or tables\n"); + goto rollback; + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, + "Dialplan: %s Action %s(%s)\n", + switch_channel_get_name(channel), application, app_data); + + switch_caller_extension_add_application(session, extension, application, app_data); + free(app_data); + free(application); + + lua_pop(L, 1); + } + + /* all went fine */ + goto done; + + rollback: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(session), SWITCH_LOG_DEBUG, + "Rollback, all applications previously added to this extension in current context/script are discarded\n"); + + /* extension was created on session's memory pool, so just make a new, empty one here */ + if ((extension = switch_caller_extension_new(session, "_anon_", caller_profile->destination_number)) == 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Memory Error!\n"); + } + + done: + switch_safe_free(cmd); + lua_uninit(L); + return extension; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load) +{ + switch_api_interface_t *api_interface; + switch_application_interface_t *app_interface; + switch_dialplan_interface_t *dp_interface; + switch_chat_application_interface_t *chat_app_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_API(api_interface, "luarun", "run a script", luarun_api_function, "