mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-24 06:38:08 +00:00
Merge branch 'master' of git.linphone.org:linphone
This commit is contained in:
commit
1b47a0dfd4
14 changed files with 1081 additions and 268 deletions
12
COPYING
12
COPYING
|
|
@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
|||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
|
|
@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
|||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
|
|
@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
|||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
|
|
@ -225,7 +225,7 @@ impose that choice.
|
|||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
|
|
@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
|
|
|
|||
|
|
@ -171,13 +171,15 @@ void linphone_address_destroy(LinphoneAddress *u){
|
|||
sal_address_unref(u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get port number as an integer value.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get port number, 0 if not present.
|
||||
*/
|
||||
int linphone_address_get_port(const LinphoneAddress *u) {
|
||||
#ifdef USE_BELLESIP
|
||||
return sal_address_get_port(u);
|
||||
#else
|
||||
return sal_address_get_port_int(u);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ EXPAND_ONLY_PREDEF = NO
|
|||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH = .
|
||||
INCLUDE_FILE_PATTERNS = *.h
|
||||
PREDEFINED = DOXYGEN
|
||||
PREDEFINED = DOXYGEN MS2_PUBLIC= LINPHONE_PUBLIC=
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1203,16 +1203,31 @@ void _linphone_call_params_copy(LinphoneCallParams *ncp, const LinphoneCallParam
|
|||
if (cp->custom_headers) ncp->custom_headers=sal_custom_header_clone(cp->custom_headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup call_control
|
||||
* Set requested level of privacy for the call.
|
||||
* \xmlonly <language-tags>javascript</language-tags> \endxmlonly
|
||||
* @param params the call parameters to be modified
|
||||
* @param LinphonePrivacy to configure privacy
|
||||
* */
|
||||
void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy) {
|
||||
params->privacy=privacy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup call_control
|
||||
* Get requested level of privacy for the call.
|
||||
* @param params the call parameters
|
||||
* @return Privacy mode
|
||||
* */
|
||||
LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *params) {
|
||||
return params->privacy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup call_control
|
||||
* @return string value of LinphonePrivacy enum
|
||||
**/
|
||||
const char* linphone_privacy_to_string(LinphonePrivacy privacy) {
|
||||
switch(privacy) {
|
||||
case LinphonePrivacyDefault: return "LinphonePrivacyDefault";
|
||||
|
|
@ -1669,7 +1684,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
|
|||
stream->rtp_addr[0]!='\0' ? stream->rtp_addr : call->resultdesc->addr,
|
||||
stream->rtp_port,
|
||||
stream->rtcp_addr[0]!='\0' ? stream->rtcp_addr : call->resultdesc->addr,
|
||||
linphone_core_rtcp_enabled(lc) ? (stream->rtcp_port) : 0,
|
||||
linphone_core_rtcp_enabled(lc) ? (stream->rtcp_port ? stream->rtcp_port : stream->rtp_port+1) : 0,
|
||||
used_pt,
|
||||
linphone_core_get_audio_jittcomp(lc),
|
||||
playfile,
|
||||
|
|
@ -1791,7 +1806,8 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
video_stream_set_device_rotation(call->videostream, lc->device_rotation);
|
||||
video_stream_start(call->videostream,
|
||||
call->video_profile, rtp_addr, vstream->rtp_port,
|
||||
rtcp_addr, linphone_core_rtcp_enabled(lc) ? (vstream->rtcp_port) : 0,
|
||||
rtcp_addr,
|
||||
linphone_core_rtcp_enabled(lc) ? (vstream->rtcp_port ? vstream->rtcp_port : vstream->rtp_port+1) : 0,
|
||||
used_pt, linphone_core_get_video_jittcomp(lc), cam);
|
||||
video_stream_set_rtcp_information(call->videostream, cname,rtcp_tool);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4891,26 +4891,58 @@ float linphone_core_get_static_picture_fps(LinphoneCore *lc) {
|
|||
* @ingroup media_parameters
|
||||
**/
|
||||
unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc){
|
||||
if (lc->video_window_id) {
|
||||
/* case where the video id was previously set by the app*/
|
||||
return lc->video_window_id;
|
||||
}else{
|
||||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCall *call=linphone_core_get_current_call (lc);
|
||||
if (call && call->videostream)
|
||||
return video_stream_get_native_window_id(call->videostream);
|
||||
if (lc->previewstream)
|
||||
return video_stream_get_native_window_id(lc->previewstream);
|
||||
/*case where it was not set but we want to get the one automatically created by mediastreamer2 (desktop versions only)*/
|
||||
LinphoneCall *call=linphone_core_get_current_call (lc);
|
||||
if (call && call->videostream)
|
||||
return video_stream_get_native_window_id(call->videostream);
|
||||
#endif
|
||||
return lc->video_window_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**@ingroup media_parameters
|
||||
/* unsets the video id for all calls (indeed it may be kept by filters or videostream object itself by paused calls)*/
|
||||
static void unset_video_window_id(LinphoneCore *lc, bool_t preview, unsigned long id){
|
||||
LinphoneCall *call;
|
||||
MSList *elem;
|
||||
|
||||
if (id!=0 && id!=-1) {
|
||||
ms_error("Invalid use of unset_video_window_id()");
|
||||
return;
|
||||
}
|
||||
#ifdef VIDEO_ENABLED
|
||||
for(elem=lc->calls;elem!=NULL;elem=elem->next){
|
||||
call=(LinphoneCall *) elem->data;
|
||||
if (call->videostream){
|
||||
if (preview)
|
||||
video_stream_set_native_preview_window_id(call->videostream,id);
|
||||
else
|
||||
video_stream_set_native_window_id(call->videostream,id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup media_parameters
|
||||
* Set the native video window id where the video is to be displayed.
|
||||
* If not set the core will create its own window.
|
||||
* For MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given.
|
||||
**/
|
||||
void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id){
|
||||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (id==0 || id==(unsigned long)-1){
|
||||
unset_video_window_id(lc,FALSE,id);
|
||||
}
|
||||
lc->video_window_id=id;
|
||||
if (call!=NULL && call->videostream){
|
||||
video_stream_set_native_window_id(call->videostream,id);
|
||||
#ifdef VIDEO_ENABLED
|
||||
{
|
||||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (call!=NULL && call->videostream){
|
||||
video_stream_set_native_window_id(call->videostream,id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -4921,30 +4953,41 @@ void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id
|
|||
* @ingroup media_parameters
|
||||
**/
|
||||
unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc){
|
||||
if (lc->preview_window_id){
|
||||
/*case where the id was set by the app previously*/
|
||||
return lc->preview_window_id;
|
||||
}else{
|
||||
/*case where we want the id automatically created by mediastreamer2 (desktop versions only)*/
|
||||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCall *call=linphone_core_get_current_call (lc);
|
||||
if (call && call->videostream)
|
||||
return video_stream_get_native_preview_window_id(call->videostream);
|
||||
if (lc->previewstream)
|
||||
return video_preview_get_native_window_id(lc->previewstream);
|
||||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (call && call->videostream)
|
||||
return video_stream_get_native_preview_window_id(call->videostream);
|
||||
if (lc->previewstream)
|
||||
return video_preview_get_native_window_id(lc->previewstream);
|
||||
#endif
|
||||
return lc->preview_window_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup media_parameters
|
||||
* Set the native window id where the preview video (local camera) is to be displayed.
|
||||
* This has to be used in conjonction with linphone_core_use_preview_window().
|
||||
* If not set the core will create its own window.
|
||||
* MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given.
|
||||
**/
|
||||
void linphone_core_set_native_preview_window_id(LinphoneCore *lc, unsigned long id){
|
||||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (id==0 || id==(unsigned long)-1){
|
||||
unset_video_window_id(lc,TRUE,id);
|
||||
}
|
||||
lc->preview_window_id=id;
|
||||
if (call!=NULL && call->videostream){
|
||||
video_stream_set_native_preview_window_id(call->videostream,id);
|
||||
}else if (lc->previewstream){
|
||||
video_preview_set_native_window_id(lc->previewstream,id);
|
||||
#ifdef VIDEO_ENABLED
|
||||
{
|
||||
LinphoneCall *call=linphone_core_get_current_call(lc);
|
||||
if (call!=NULL && call->videostream){
|
||||
video_stream_set_native_preview_window_id(call->videostream,id);
|
||||
}else if (lc->previewstream){
|
||||
video_preview_set_native_window_id(lc->previewstream,id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,9 +182,6 @@ const char *linphone_address_get_scheme(const LinphoneAddress *u);
|
|||
LINPHONE_PUBLIC const char *linphone_address_get_display_name(const LinphoneAddress* u);
|
||||
LINPHONE_PUBLIC const char *linphone_address_get_username(const LinphoneAddress *u);
|
||||
LINPHONE_PUBLIC const char *linphone_address_get_domain(const LinphoneAddress *u);
|
||||
/**
|
||||
* Get port number as an integer value, -1 if not set.
|
||||
*/
|
||||
LINPHONE_PUBLIC int linphone_address_get_port(const LinphoneAddress *u);
|
||||
LINPHONE_PUBLIC void linphone_address_set_display_name(LinphoneAddress *u, const char *display_name);
|
||||
LINPHONE_PUBLIC void linphone_address_set_username(LinphoneAddress *uri, const char *username);
|
||||
|
|
@ -371,24 +368,9 @@ typedef enum _LinphonePrivacy {
|
|||
* */
|
||||
typedef unsigned int LinphonePrivacyMask;
|
||||
|
||||
/**
|
||||
* @ingroup call_control
|
||||
* @return string value of LinphonePrivacy enum
|
||||
* */
|
||||
const char* linphone_privacy_to_string(LinphonePrivacy privacy);
|
||||
/**
|
||||
* @ingroup call_control
|
||||
* Set requested level of privacy for the call.
|
||||
* @param params the call parameters to be modified
|
||||
* @param LinphonePrivacy to configure privacy
|
||||
* */
|
||||
|
||||
LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy);
|
||||
LINPHONE_PUBLIC void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy);
|
||||
/**
|
||||
* @ingroup call_control
|
||||
* Get requested level of privacy for the call.
|
||||
* @param params the call parameters
|
||||
* @return Privacy mode
|
||||
* */
|
||||
LINPHONE_PUBLIC LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *params);
|
||||
|
||||
|
||||
|
|
@ -975,9 +957,9 @@ typedef void (*NotifyPresenceReceivedCb)(struct _LinphoneCore *lc, LinphoneFrien
|
|||
* */
|
||||
typedef void (*NewSubscribtionRequestCb)(struct _LinphoneCore *lc, LinphoneFriend *lf, const char *url);
|
||||
/** Callback prototype */
|
||||
typedef void (*AuthInfoRequested)(struct _LinphoneCore *lc, const char *realm, const char *username);
|
||||
typedef void (*AuthInfoRequestedCb)(struct _LinphoneCore *lc, const char *realm, const char *username);
|
||||
/** Callback prototype */
|
||||
typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl);
|
||||
typedef void (*CallLogUpdatedCb)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl);
|
||||
/**
|
||||
* Callback prototype
|
||||
* @deprecated use #MessageReceived instead.
|
||||
|
|
@ -987,7 +969,7 @@ typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog
|
|||
* @param from #LinphoneAddress from
|
||||
* @param message incoming message
|
||||
* */
|
||||
typedef void (*TextMessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message);
|
||||
typedef void (*TextMessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message);
|
||||
/**
|
||||
* Chat message callback prototype
|
||||
*
|
||||
|
|
@ -995,18 +977,18 @@ typedef void (*TextMessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, co
|
|||
* @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room.
|
||||
* @param LinphoneChatMessage incoming message
|
||||
* */
|
||||
typedef void (*MessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
|
||||
typedef void (*MessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
|
||||
|
||||
/** Callback prototype */
|
||||
typedef void (*DtmfReceived)(struct _LinphoneCore* lc, LinphoneCall *call, int dtmf);
|
||||
typedef void (*DtmfReceivedCb)(struct _LinphoneCore* lc, LinphoneCall *call, int dtmf);
|
||||
/** Callback prototype */
|
||||
typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to);
|
||||
typedef void (*ReferReceivedCb)(struct _LinphoneCore *lc, const char *refer_to);
|
||||
/** Callback prototype */
|
||||
typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf);
|
||||
typedef void (*BuddyInfoUpdatedCb)(struct _LinphoneCore *lc, LinphoneFriend *lf);
|
||||
/** Callback prototype for in progress transfers. The new_call_state is the state of the call resulting of the transfer, at the other party. */
|
||||
typedef void (*LinphoneTransferStateChanged)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state);
|
||||
typedef void (*LinphoneTransferStateChangedCb)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state);
|
||||
/** Callback prototype for receiving quality statistics for calls*/
|
||||
typedef void (*CallStatsUpdated)(struct _LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats);
|
||||
typedef void (*CallStatsUpdatedCb)(struct _LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats);
|
||||
|
||||
/** Callback prototype for receiving info messages*/
|
||||
typedef void (*LinphoneInfoReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg);
|
||||
|
|
@ -1020,15 +1002,15 @@ typedef struct _LinphoneVTable{
|
|||
LinphoneCallStateCb call_state_changed;/**<Notifies call state changes*/
|
||||
NotifyPresenceReceivedCb notify_presence_recv; /**< Notify received presence events*/
|
||||
NewSubscribtionRequestCb new_subscription_request; /**< Notify about pending presence subscription request */
|
||||
AuthInfoRequested auth_info_requested; /**< Ask the application some authentication information */
|
||||
CallLogUpdated call_log_updated; /**< Notifies that call log list has been updated */
|
||||
MessageReceived message_received; /** a message is received, can be text or external body*/
|
||||
DtmfReceived dtmf_received; /**< A dtmf has been received received */
|
||||
ReferReceived refer_received; /**< An out of call refer was received */
|
||||
AuthInfoRequestedCb auth_info_requested; /**< Ask the application some authentication information */
|
||||
CallLogUpdatedCb call_log_updated; /**< Notifies that call log list has been updated */
|
||||
MessageReceivedCb message_received; /** a message is received, can be text or external body*/
|
||||
DtmfReceivedCb dtmf_received; /**< A dtmf has been received received */
|
||||
ReferReceivedCb refer_received; /**< An out of call refer was received */
|
||||
CallEncryptionChangedCb call_encryption_changed; /**<Notifies on change in the encryption of call streams */
|
||||
LinphoneTransferStateChanged transfer_state_changed; /**<Notifies when a transfer is in progress */
|
||||
BuddyInfoUpdated buddy_info_updated; /**< a LinphoneFriend's BuddyInfo has changed*/
|
||||
CallStatsUpdated call_stats_updated; /**<Notifies on refreshing of call's statistics. */
|
||||
LinphoneTransferStateChangedCb transfer_state_changed; /**<Notifies when a transfer is in progress */
|
||||
BuddyInfoUpdatedCb buddy_info_updated; /**< a LinphoneFriend's BuddyInfo has changed*/
|
||||
CallStatsUpdatedCb call_stats_updated; /**<Notifies on refreshing of call's statistics. */
|
||||
LinphoneInfoReceivedCb info_received; /**<Notifies an incoming informational message received.*/
|
||||
LinphoneSubscriptionStateChangedCb subscription_state_changed; /**<Notifies subscription state change */
|
||||
LinphoneEventIncomingNotifyCb notify_received; /**< Notifies a an event notification, see linphone_core_subscribe() */
|
||||
|
|
@ -1038,7 +1020,7 @@ typedef struct _LinphoneVTable{
|
|||
DisplayMessageCb display_warning;/**< @deprecated Callback to display a warning to the user */
|
||||
DisplayUrlCb display_url; /**< @deprecated */
|
||||
ShowInterfaceCb show; /**< @deprecated Notifies the application that it should show up*/
|
||||
TextMessageReceived text_received; /** @deprecated, use #message_received instead <br> A text message has been received */
|
||||
TextMessageReceivedCb text_received; /** @deprecated, use #message_received instead <br> A text message has been received */
|
||||
} LinphoneCoreVTable;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2379,9 +2379,11 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv*
|
|||
jobject oldWindow = (jobject) linphone_core_get_native_video_window_id((LinphoneCore*)lc);
|
||||
if (obj != NULL) {
|
||||
obj = env->NewGlobalRef(obj);
|
||||
}
|
||||
ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): NewGlobalRef(%p)",obj);
|
||||
}else ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): setting to NULL");
|
||||
linphone_core_set_native_video_window_id((LinphoneCore*)lc,(unsigned long)obj);
|
||||
if (oldWindow != NULL) {
|
||||
ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): DeleteGlobalRef(%p)",oldWindow);
|
||||
env->DeleteGlobalRef(oldWindow);
|
||||
}
|
||||
}
|
||||
|
|
@ -2393,9 +2395,11 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(JNIEn
|
|||
jobject oldWindow = (jobject) linphone_core_get_native_preview_window_id((LinphoneCore*)lc);
|
||||
if (obj != NULL) {
|
||||
obj = env->NewGlobalRef(obj);
|
||||
}
|
||||
ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): NewGlobalRef(%p)",obj);
|
||||
}else ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): setting to NULL");
|
||||
linphone_core_set_native_preview_window_id((LinphoneCore*)lc,(unsigned long)obj);
|
||||
if (oldWindow != NULL) {
|
||||
ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): DeleteGlobalRef(%p)",oldWindow);
|
||||
env->DeleteGlobalRef(oldWindow);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 5b941cb169940ae643de86e957daa86c31c25145
|
||||
Subproject commit 214f82f8942f9d1c419f038dbd33b36b65e2a1e6
|
||||
|
|
@ -12,7 +12,7 @@ COMMON_CFLAGS=\
|
|||
$(STRICT_OPTIONS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
AM_CXXFLAGS=$(LIBXML2_CFLAGS)
|
||||
AM_CXXFLAGS=$(LIBXML2_CFLAGS) $(STRICT_OPTIONS)
|
||||
|
||||
EXTRA_DIST=xml2lpc_jni.cc lpc2xml_jni.cc
|
||||
|
||||
|
|
@ -59,7 +59,9 @@ lpc2xml_test_LDADD=\
|
|||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
liblpc2xml.la
|
||||
|
||||
lp_gen_wrappers_SOURCES=genwrappers.cc
|
||||
lp_gen_wrappers_SOURCES=genwrappers.cc \
|
||||
software-desc.cc software-desc.hh \
|
||||
generator.cc generator.hh
|
||||
|
||||
lp_gen_wrappers_LDADD= \
|
||||
$(LIBXML2_LIBS)
|
||||
|
|
|
|||
284
tools/generator.cc
Normal file
284
tools/generator.cc
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2013 Belledonne Communications SARL
|
||||
Simon Morlat (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "generator.hh"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
|
||||
CplusplusGenerator::CplusplusGenerator(){
|
||||
}
|
||||
|
||||
void CplusplusGenerator::generate(Project *proj){
|
||||
list<Class*> classes=proj->getClasses();
|
||||
mCurProj=proj;
|
||||
#ifndef WIN32
|
||||
mkdir(proj->getName().c_str(),S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH);
|
||||
#else
|
||||
_mkdir(proj->getName().c_str());
|
||||
#endif
|
||||
for_each(classes.begin(),classes.end(),bind1st(mem_fun(&CplusplusGenerator::writeClass),this));
|
||||
}
|
||||
|
||||
void CplusplusGenerator::writeClass(Class *klass){
|
||||
ostringstream filename;
|
||||
|
||||
if (klass->getType()!=Type::Class) return;
|
||||
filename<<mCurProj->getName()<<"/"<<klass->getName()<<".hh";
|
||||
mOutfile.open(filename.str().c_str());
|
||||
if (!mOutfile.is_open()){
|
||||
cerr<<"Could not write into "<<filename.str()<<endl;
|
||||
return;
|
||||
}
|
||||
const list<Method*> &methods=klass->getMethods();
|
||||
mCurClass=klass;
|
||||
mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<<endl;
|
||||
mOutfile<<endl;
|
||||
mOutfile<<"#include <string>"<<endl;
|
||||
mOutfile<<endl;
|
||||
if (!mCurProj->getName().empty())
|
||||
mOutfile<<"namespace "<<mCurProj->getName()<<"{"<<endl<<endl;
|
||||
mOutfile<<"class "<<klass->getName()<<"{"<<endl;
|
||||
mOutfile<<"public:"<<endl;
|
||||
for_each(methods.begin(),methods.end(),bind1st(mem_fun(&CplusplusGenerator::writeMethod),this));
|
||||
mOutfile<<"}"<<endl<<endl;
|
||||
if (!mCurProj->getName().empty())
|
||||
mOutfile<<"} //end of namespace "<<mCurProj->getName()<<endl;
|
||||
mOutfile<<endl;
|
||||
mOutfile.close();
|
||||
}
|
||||
|
||||
void CplusplusGenerator::writeArgument(Argument *arg, bool isReturn){
|
||||
Type *type=arg->getType();
|
||||
|
||||
if (type->getBasicType()==Type::Class){
|
||||
if (arg->isConst()){
|
||||
mOutfile<<"const ";
|
||||
}
|
||||
mOutfile<<type->getName();
|
||||
if (arg->isPointer())
|
||||
mOutfile<<"*";
|
||||
}else if (type->getBasicType()==Type::Integer){
|
||||
mOutfile<<"int";
|
||||
}else if (type->getBasicType()==Type::Enum){
|
||||
mOutfile<<type->getName();
|
||||
}else if (type->getBasicType()==Type::String){
|
||||
if (!isReturn)
|
||||
mOutfile<<"const std::string &";
|
||||
else
|
||||
mOutfile<<"std::string";
|
||||
}else if (type->getBasicType()==Type::Void){
|
||||
mOutfile<<"void";
|
||||
}else if (type->getBasicType()==Type::Boolean){
|
||||
mOutfile<<"bool";
|
||||
}
|
||||
if (!isReturn && !arg->getName().empty())
|
||||
mOutfile<<" "<<arg->getName();
|
||||
}
|
||||
|
||||
void CplusplusGenerator::writeTabs(int ntabs){
|
||||
int i;
|
||||
for(i=0;i<ntabs;++i)
|
||||
mOutfile<<"\t";
|
||||
}
|
||||
|
||||
void CplusplusGenerator::writeHelpComment(const std::string &comment, int ntabs){
|
||||
size_t i;
|
||||
int curindex=0;
|
||||
writeTabs(ntabs);
|
||||
mOutfile<<" * ";
|
||||
for(i=0;i<comment.size();i++,curindex++){
|
||||
|
||||
if (comment[i]=='\n' || (curindex>100 && comment[i]==' ')){
|
||||
mOutfile<<endl;
|
||||
writeTabs(ntabs);
|
||||
mOutfile<<" * ";
|
||||
curindex=0;
|
||||
}else mOutfile<<comment[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CplusplusGenerator::writeMethod(Method *method){
|
||||
Argument *retarg=method->getReturnArg();
|
||||
const list<Argument*> &args=method->getArgs();
|
||||
list<Argument*>::const_iterator it;
|
||||
|
||||
writeTabs(1);
|
||||
mOutfile<<"/**"<<endl;
|
||||
writeHelpComment(method->getHelp(),1);
|
||||
mOutfile<<endl;
|
||||
writeTabs(1);
|
||||
mOutfile<<"**/"<<endl;
|
||||
|
||||
writeTabs(1);
|
||||
writeArgument(retarg,true);
|
||||
mOutfile<<" "<<method->getName()<<"(";
|
||||
|
||||
for(it=args.begin();it!=args.end();++it){
|
||||
if (it!=args.begin()) mOutfile<<", ";
|
||||
writeArgument(*it);
|
||||
}
|
||||
mOutfile<<")";
|
||||
if (method->isConst()) mOutfile<<"const";
|
||||
mOutfile<<";"<<endl;
|
||||
mOutfile<<endl;
|
||||
}
|
||||
|
||||
|
||||
JavascriptGenerator::JavascriptGenerator(){
|
||||
}
|
||||
|
||||
void JavascriptGenerator::generate(Project *proj){
|
||||
list<Class*> classes=proj->getClasses();
|
||||
mCurProj=proj;
|
||||
#ifndef WIN32
|
||||
unlink(proj->getName().c_str());
|
||||
mkdir(proj->getName().c_str(),S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH);
|
||||
#else
|
||||
_mkdir(proj->getName().c_str());
|
||||
#endif
|
||||
for_each(classes.begin(),classes.end(),bind1st(mem_fun(&JavascriptGenerator::writeClass),this));
|
||||
}
|
||||
|
||||
void JavascriptGenerator::writeClass(Class *klass){
|
||||
ostringstream filename;
|
||||
|
||||
if (klass->getType()!=Type::Class) return;
|
||||
filename<<mCurProj->getName()<<"/"<<klass->getName()<<".js";
|
||||
mOutfile.open(filename.str().c_str());
|
||||
if (!mOutfile.is_open()){
|
||||
cerr<<"Could not write into "<<filename.str()<<endl;
|
||||
return;
|
||||
}
|
||||
const list<Method*> &methods=klass->getMethods();
|
||||
mCurClass=klass;
|
||||
mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<<endl;
|
||||
mOutfile<<endl;
|
||||
|
||||
//if (!mCurProj->getName().empty())
|
||||
// mOutfile<<"namespace "<<mCurProj->getName()<<"{"<<endl<<endl;
|
||||
mOutfile<<"/**"<<endl;
|
||||
mOutfile<<" * "<<klass->getHelp()<<endl;
|
||||
mOutfile<<" * @external "<<klass->getName()<<endl;
|
||||
mOutfile<<"**/"<<endl;
|
||||
|
||||
list<Property*> properties=klass->getProperties();
|
||||
for_each(properties.begin(),properties.end(),bind1st(mem_fun(&JavascriptGenerator::writeProperty),this));
|
||||
mOutfile<<endl;
|
||||
for_each(methods.begin(),methods.end(),bind1st(mem_fun(&JavascriptGenerator::writeMethod),this));
|
||||
//if (!mCurProj->getName().empty())
|
||||
// mOutfile<<"} //end of namespace "<<mCurProj->getName()<<endl;
|
||||
mOutfile<<endl;
|
||||
mOutfile.close();
|
||||
}
|
||||
|
||||
void JavascriptGenerator::writeType(Type *type){
|
||||
switch(type->getBasicType()){
|
||||
case Type::Float:
|
||||
case Type::Integer:
|
||||
mOutfile<<"number";
|
||||
break;
|
||||
case Type::String:
|
||||
mOutfile<<"string";
|
||||
break;
|
||||
case Type::Boolean:
|
||||
mOutfile<<"boolean";
|
||||
break;
|
||||
case Type::Class:
|
||||
case Type::Enum:
|
||||
mOutfile<<"external:"<<type->getName();
|
||||
break;
|
||||
case Type::Void:
|
||||
mOutfile<<"void";
|
||||
break;
|
||||
case Type::Callback:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JavascriptGenerator::writeArgument(Argument *arg, bool isReturn){
|
||||
if (!isReturn){
|
||||
mOutfile<<" * @param {";
|
||||
writeType(arg->getType());
|
||||
mOutfile<<"} "<<arg->getName()<<" - "<<arg->getHelp()<<endl;
|
||||
}else{
|
||||
mOutfile<<" * @returns {";
|
||||
writeType(arg->getType());
|
||||
mOutfile<<"} "<<arg->getHelp()<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
void JavascriptGenerator::writeTabs(int ntabs){
|
||||
int i;
|
||||
for(i=0;i<ntabs;++i)
|
||||
mOutfile<<"\t";
|
||||
}
|
||||
|
||||
void JavascriptGenerator::writeHelpComment(const std::string &comment, int ntabs){
|
||||
size_t i;
|
||||
int curindex=0;
|
||||
mOutfile<<" * ";
|
||||
for(i=0;i<comment.size();i++,curindex++){
|
||||
|
||||
if (comment[i]=='\n' || (curindex>100 && comment[i]==' ')){
|
||||
mOutfile<<endl;
|
||||
mOutfile<<" * ";
|
||||
curindex=0;
|
||||
}else mOutfile<<comment[i];
|
||||
}
|
||||
}
|
||||
|
||||
void JavascriptGenerator::writeProperty(Property *prop){
|
||||
mOutfile<<"/**"<<endl;
|
||||
writeHelpComment(prop->getHelp(),0);
|
||||
mOutfile<<endl;
|
||||
mOutfile<<" * @member {";
|
||||
writeType(prop->getType());
|
||||
mOutfile<<"} external:"<<mCurClass->getName()<<"#"<<prop->getName()<<endl;
|
||||
if (prop->getAttribute()==Property::ReadOnly)
|
||||
mOutfile<<" * @readonly"<<endl;
|
||||
mOutfile<<"**/"<<endl;
|
||||
}
|
||||
|
||||
void JavascriptGenerator::writeMethod(Method *method){
|
||||
Argument *retarg=method->getReturnArg();
|
||||
const list<Argument*> &args=method->getArgs();
|
||||
list<Argument*>::const_iterator it;
|
||||
|
||||
if (method->getPropertyBehaviour()!=Method::None) return;
|
||||
if (method->getName()=="ref" || method->getName()=="unref") return;
|
||||
|
||||
mOutfile<<"/**"<<endl;
|
||||
writeHelpComment(method->getHelp(),0);
|
||||
mOutfile<<endl;
|
||||
mOutfile<<" * @function external:"<<mCurClass->getName()<<"#"<<method->getName()<<endl;
|
||||
|
||||
for(it=args.begin();it!=args.end();++it){
|
||||
writeArgument(*it);
|
||||
}
|
||||
writeArgument(retarg,true);
|
||||
mOutfile<<"**/"<<endl;
|
||||
mOutfile<<endl;
|
||||
}
|
||||
66
tools/generator.hh
Normal file
66
tools/generator.hh
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2013 Belledonne Communications SARL
|
||||
Simon Morlat (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef generator_hh
|
||||
#define generator_hh
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "software-desc.hh"
|
||||
|
||||
class OutputGenerator{
|
||||
public:
|
||||
virtual void generate(Project *proj)=0;
|
||||
};
|
||||
|
||||
class CplusplusGenerator : public OutputGenerator{
|
||||
public:
|
||||
CplusplusGenerator();
|
||||
virtual void generate(Project *proj);
|
||||
private:
|
||||
void writeClass(Class *klass);
|
||||
void writeArgument(Argument *arg, bool isReturn=false);
|
||||
void writeTabs(int ntabs);
|
||||
void writeHelpComment(const std::string &comment, int ntabs);
|
||||
void writeMethod(Method *method);
|
||||
ofstream mOutfile;
|
||||
Project *mCurProj;
|
||||
Class *mCurClass;
|
||||
};
|
||||
|
||||
class JavascriptGenerator : public OutputGenerator{
|
||||
public:
|
||||
JavascriptGenerator();
|
||||
virtual void generate(Project *proj);
|
||||
private:
|
||||
void writeClass(Class *klass);
|
||||
void writeType(Type *type);
|
||||
void writeArgument(Argument *arg, bool isReturn=false);
|
||||
void writeTabs(int ntabs);
|
||||
void writeHelpComment(const std::string &comment, int ntabs);
|
||||
void writeProperty(Property *prop);
|
||||
void writeMethod(Method *method);
|
||||
ofstream mOutfile;
|
||||
Project *mCurProj;
|
||||
Class *mCurClass;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -18,147 +18,17 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "software-desc.hh"
|
||||
#include "generator.hh"
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <string.h>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
using namespace::std;
|
||||
|
||||
|
||||
class Type{
|
||||
public:
|
||||
enum BasicType{
|
||||
Integer,
|
||||
String,
|
||||
Klass
|
||||
};
|
||||
static Type *getType(const std::string &tname){
|
||||
if (strstr(tname.c_str(),"char")!=0 && strchr(tname.c_str(),'*')!=0){
|
||||
return &sStringType;
|
||||
}else if (strcmp(tname.c_str(),"int")==0){
|
||||
return &sIntegerType;
|
||||
}else{
|
||||
Type* ret;
|
||||
string tmp=tname;
|
||||
ssize_t pos;
|
||||
|
||||
/*really ugly and slow*/
|
||||
|
||||
pos=tmp.find('*');
|
||||
if (pos!=string::npos)
|
||||
tmp.erase(pos,1);
|
||||
|
||||
pos=tmp.find("const");
|
||||
if (pos!=string::npos)
|
||||
tmp.erase(pos,strlen("const"));
|
||||
|
||||
while ((pos=tmp.find(' '))!=string::npos){
|
||||
tmp.erase(pos,1);
|
||||
}
|
||||
|
||||
if ((ret=mTypes[tmp])==0){
|
||||
cout<<"Adding new class type '"<<tmp<<"'"<<endl;
|
||||
ret=mTypes[tmp]=new Type(Type::Klass,tmp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
cout<<"Unhandled type name"<<tname<<endl;
|
||||
return NULL;
|
||||
}
|
||||
const string &getName()const{
|
||||
return mName;
|
||||
}
|
||||
private:
|
||||
BasicType mBasic;
|
||||
string mName;
|
||||
Type(BasicType basic, const std::string &tname="") : mBasic(basic), mName(tname){
|
||||
}
|
||||
static Type sStringType;
|
||||
static Type sIntegerType;
|
||||
static std::map<string,Type*> mTypes;
|
||||
};
|
||||
|
||||
Type Type::sStringType(Type::String);
|
||||
Type Type::sIntegerType(Type::Integer);
|
||||
std::map<string,Type*> Type::mTypes;
|
||||
|
||||
class Argument{
|
||||
public:
|
||||
Argument(Type *type, const string &argname, bool isConst) : mType(type), mName(argname), mConst(isConst){
|
||||
}
|
||||
Type *getType()const{
|
||||
return mType;
|
||||
}
|
||||
private:
|
||||
bool mConst;
|
||||
Type *mType;
|
||||
string mName;
|
||||
string mHelp;
|
||||
};
|
||||
|
||||
class Method{
|
||||
public:
|
||||
Method(const std::string &uid, Argument* return_arg, const std::string &name, const list<Argument*> &args){
|
||||
mUid=uid;
|
||||
mReturn=return_arg;
|
||||
mName=name;
|
||||
mArgs=args;
|
||||
}
|
||||
void setHelp(const std::string &help){
|
||||
mHelp=help;
|
||||
}
|
||||
private:
|
||||
string mUid;
|
||||
Argument *mReturn;
|
||||
string mName;
|
||||
list<Argument*> mArgs;
|
||||
string mHelp;
|
||||
};
|
||||
|
||||
class Class{
|
||||
public:
|
||||
Class(const std::string &name): mName(name){
|
||||
}
|
||||
void addMethod(Method *method){
|
||||
mMethods.push_back(method);
|
||||
}
|
||||
void setHelp(const std::string &help){
|
||||
mHelp=help;
|
||||
}
|
||||
private:
|
||||
list<Method*> mMethods;
|
||||
string mName;
|
||||
string mHelp;
|
||||
};
|
||||
|
||||
class Project{
|
||||
public:
|
||||
Class *getClass(const std::string &name){
|
||||
Class *ret;
|
||||
if ((ret=mClasses[name])==NULL){
|
||||
ret=mClasses[name]=new Class(name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
private:
|
||||
map<string,Class*> mClasses;
|
||||
};
|
||||
|
||||
static xmlNode * findChild(xmlNode *a_node, const char *element_name){
|
||||
xmlNode *cur_node;
|
||||
|
||||
for (cur_node = a_node->children; cur_node != NULL ; cur_node = cur_node->next){
|
||||
if (strcmp((const char*)cur_node->name,(const char*)element_name)==0){
|
||||
return cur_node;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool isSpace(const char *str){
|
||||
for(;*str!='\0';++str){
|
||||
|
|
@ -167,45 +37,101 @@ static bool isSpace(const char *str){
|
|||
return true;
|
||||
}
|
||||
|
||||
static string findChildContent(xmlNode *a_node, const char *element_name){
|
||||
xmlNode *node=findChild(a_node,element_name);
|
||||
string res;
|
||||
if (node) {
|
||||
xmlChar *text=xmlNodeGetContent(node);
|
||||
if (!isSpace((const char*)text))
|
||||
res=(char*)text;
|
||||
xmlFree(text);
|
||||
//Convenient class for examining node recursively
|
||||
class XmlNode{
|
||||
public:
|
||||
XmlNode(const xmlNode *node=NULL) : mNode(node){
|
||||
}
|
||||
return res;
|
||||
}
|
||||
XmlNode getChild(const string &name)const{
|
||||
if (mNode==NULL) return XmlNode();
|
||||
xmlNode *it;
|
||||
for(it=mNode->children;it!=NULL;it=it->next){
|
||||
if (xmlStrcmp(it->name,(const xmlChar*)name.c_str())==0)
|
||||
return XmlNode(it);
|
||||
}
|
||||
return XmlNode();
|
||||
}
|
||||
XmlNode getChildRecursive(const string &name)const{
|
||||
if (mNode==NULL) return XmlNode();
|
||||
xmlNode *it;
|
||||
//find in direct children
|
||||
for(it=mNode->children;it!=NULL;it=it->next){
|
||||
if (xmlStrcmp(it->name,(const xmlChar*)name.c_str())==0)
|
||||
return XmlNode(it);
|
||||
}
|
||||
//recurse into children
|
||||
for(it=mNode->children;it!=NULL;it=it->next){
|
||||
XmlNode res=XmlNode(it).getChildRecursive(name);
|
||||
if (!res.isNull()) return res;
|
||||
}
|
||||
return XmlNode();
|
||||
}
|
||||
list<XmlNode> getChildren(const string &name)const{
|
||||
xmlNode *it;
|
||||
list<XmlNode> nodes;
|
||||
|
||||
if (mNode==NULL) return nodes;
|
||||
for(it=mNode->children;it!=NULL;it=it->next){
|
||||
if (xmlStrcmp(it->name,(const xmlChar*)name.c_str())==0)
|
||||
nodes.push_back(XmlNode(it));
|
||||
}
|
||||
if (nodes.empty()) cerr<<"getChildren() no "<<name<<" found"<<endl;
|
||||
return nodes;
|
||||
}
|
||||
string getText()const{
|
||||
if (mNode==NULL) return "";
|
||||
XmlNode node=getChild("text");
|
||||
if (!node.isNull()) {
|
||||
const char *text=(const char*)node.mNode->content;
|
||||
if (!isSpace(text)) return string(text);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
string getProp(const string &propname)const{
|
||||
if (mNode==NULL) return "";
|
||||
xmlChar *value;
|
||||
value=xmlGetProp((xmlNode*)mNode,(const xmlChar*)propname.c_str());
|
||||
if (value) return string((const char*)value);
|
||||
return "";
|
||||
}
|
||||
bool isNull()const{
|
||||
return mNode==NULL;
|
||||
}
|
||||
private:
|
||||
const xmlNode *mNode;
|
||||
};
|
||||
|
||||
#define nullOrEmpty(p) (p==NULL || *p=='\0')
|
||||
|
||||
static Argument *parseArgument(xmlNode *node){
|
||||
string name=findChildContent(node,"name");
|
||||
static Argument *parseArgument(XmlNode node, bool isReturn){
|
||||
string name=node.getChild("declname").getText();
|
||||
Type *type=NULL;
|
||||
string typecontent=node.getChild("type").getText();
|
||||
bool isConst=false;
|
||||
bool isPointer=false;
|
||||
|
||||
xmlNode *typenode=findChild(node,"type");
|
||||
//find documented type if any
|
||||
string tname=node.getChild("type").getChild("ref").getText();
|
||||
if (!tname.empty()){
|
||||
type=Type::getType(tname);
|
||||
}else type=Type::getType(typecontent);
|
||||
|
||||
if (!typenode) {
|
||||
cout<<"Cannot find type from node."<<endl;
|
||||
return NULL;
|
||||
}
|
||||
//find const attribute if any
|
||||
if (typecontent.find("const")!=string::npos)
|
||||
isConst=true;
|
||||
|
||||
if (typecontent.find("*")!=string::npos)
|
||||
isPointer=true;
|
||||
|
||||
string tname=findChildContent(typenode,"ref");
|
||||
if (tname.empty()){
|
||||
return NULL;
|
||||
}
|
||||
Type *type=Type::getType(tname);
|
||||
if (type==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return new Argument(type,name,false);
|
||||
//cout<<"Parsed argument "<<name<<" with type "<<type->getBasicType()<<" "<<type->getName()<<endl;
|
||||
return new Argument(type,!isReturn ? name : "",isConst,isPointer);
|
||||
}
|
||||
|
||||
static string classNameToPrefix(const std::string &classname){
|
||||
char tmp[classname.size()*2];
|
||||
char *w=tmp;
|
||||
ssize_t i;
|
||||
size_t i;
|
||||
|
||||
for(i=0;i<classname.size();i++){
|
||||
char p=classname[i];
|
||||
|
|
@ -223,7 +149,7 @@ static string classNameToPrefix(const std::string &classname){
|
|||
static string makeMethodName(const string & suffix){
|
||||
char tmp[suffix.size()];
|
||||
char *w=tmp;
|
||||
ssize_t i;
|
||||
size_t i;
|
||||
bool useUpper=false;
|
||||
|
||||
for(i=0;i<suffix.size();i++){
|
||||
|
|
@ -252,50 +178,106 @@ static string extractMethodName(const string &c_name, const std::string& class_n
|
|||
return "";
|
||||
}
|
||||
|
||||
static string getHelpBody(XmlNode myNode){
|
||||
ostringstream result;
|
||||
XmlNode brief=myNode.getChild("briefdescription");
|
||||
XmlNode detailed=myNode.getChild("detaileddescription");
|
||||
|
||||
result<<brief.getText();
|
||||
result<<detailed.getChild("para").getText();
|
||||
//cout<<"getHelpBody():"<<result.str();
|
||||
return result.str();
|
||||
}
|
||||
|
||||
static void parseFunction(Project *proj, xmlNode *node){
|
||||
string name;
|
||||
Argument *first_arg=NULL;
|
||||
xmlNode *cur_node;
|
||||
string className;
|
||||
string methodName;
|
||||
Argument *retarg=NULL;
|
||||
list<Argument*> args;
|
||||
string help;
|
||||
XmlNode funcnode(node);
|
||||
XmlNode parameterlist;
|
||||
list<XmlNode> params;
|
||||
list<XmlNode> paramsHelp;
|
||||
list<XmlNode>::iterator it,helpit;
|
||||
|
||||
for (cur_node = node->children; cur_node != NULL ; cur_node = cur_node->next){
|
||||
if (strcmp((const char*)cur_node->name,"name")==0){
|
||||
xmlChar *content=xmlNodeGetContent(cur_node);
|
||||
name=(const char*)content;
|
||||
xmlFree(content);
|
||||
}else if (strcmp((const char*)cur_node->name,"param")==0){
|
||||
if (first_arg==NULL){
|
||||
first_arg=parseArgument(cur_node);
|
||||
name=funcnode.getChild("name").getText();
|
||||
params=funcnode.getChildren("param");
|
||||
parameterlist=funcnode.getChild("detaileddescription").getChildRecursive("parameterlist");
|
||||
if (parameterlist.isNull()) cerr<<"parameterlist not found"<<endl;
|
||||
paramsHelp=parameterlist.getChildren("parameteritem");
|
||||
|
||||
for (it=params.begin(),helpit=paramsHelp.begin();it!=params.end();++it){
|
||||
Argument *a=parseArgument(*it,false);
|
||||
if (a){
|
||||
//add argument help
|
||||
if (!args.empty()){
|
||||
if (helpit!=paramsHelp.end()){
|
||||
XmlNode item=*helpit;
|
||||
a->setHelp(item.getChild("parameterdescription").getChild("para").getText());
|
||||
}else cerr<<"Undocumented parameter "<<a->getName()<<" in function "<<name<<endl;
|
||||
}
|
||||
args.push_back(a);
|
||||
if (helpit!=paramsHelp.end()) ++helpit;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
help=getHelpBody(funcnode);
|
||||
|
||||
retarg=parseArgument(funcnode,true);
|
||||
if (!retarg){
|
||||
cerr<<"Could not parse return argument of function "<<name<<endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args.empty()) first_arg=args.front();
|
||||
if (!first_arg){
|
||||
cout<<"Could not determine first argument of "<<name<<endl;
|
||||
return;
|
||||
}
|
||||
if (first_arg->getType()->getBasicType()!=Type::Class) return;
|
||||
className=first_arg->getType()->getName();
|
||||
methodName=extractMethodName(name,className);
|
||||
if (!methodName.empty()){
|
||||
cout<<"Found "<<className<<"."<<methodName<<"()"<<endl;
|
||||
if (!methodName.empty() && methodName!="destroy"){
|
||||
//cout<<"Found "<<className<<"."<<methodName<<"()"<<endl;
|
||||
args.pop_front();
|
||||
Method *method=new Method("",retarg,methodName,args,first_arg->isConst(),false);
|
||||
method->setHelp(help);
|
||||
proj->getClass(className)->addMethod(method);
|
||||
delete first_arg;
|
||||
}
|
||||
}
|
||||
|
||||
static void parseTypedef(Project *proj, xmlNode *node){
|
||||
XmlNode tdef(node);
|
||||
string typecontent=tdef.getChild("type").getText();
|
||||
string name=tdef.getChild("name").getText();
|
||||
if (typecontent.find("enum")==0){
|
||||
Type::addType(Type::Enum,name);
|
||||
}else if (typecontent.find("void(*")==0){
|
||||
// callbacks function, not really well parsed by doxygen
|
||||
Type::addType(Type::Callback,name);
|
||||
}else
|
||||
proj->getClass(name)->setHelp(getHelpBody(node));
|
||||
}
|
||||
|
||||
static void parseMemberDef(Project *proj, xmlNode *node){
|
||||
XmlNode member(node);
|
||||
string brief;
|
||||
string detailed;
|
||||
const xmlChar *kind;
|
||||
string kind;
|
||||
|
||||
brief=findChildContent(node,"briefdescription");
|
||||
detailed=findChildContent(node,"detaileddescription");
|
||||
|
||||
if (brief.empty() && detailed.empty())
|
||||
if (member.getChild("briefdescription").getText().empty() &&
|
||||
member.getChild("detaileddescription").getChild("para").getText().empty())
|
||||
return;
|
||||
|
||||
kind=xmlGetProp(node,(const xmlChar*)"kind");
|
||||
//cout<<"Kind="<<(const char*)kind<<endl;
|
||||
if (kind && xmlStrcmp(kind,(const xmlChar*)"function")==0){
|
||||
kind=member.getProp("kind");
|
||||
if (kind=="function"){
|
||||
parseFunction(proj,node);
|
||||
}else if (kind=="typedef"){
|
||||
parseTypedef(proj,node);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,23 +316,46 @@ static int parse_file(Project *proj, const char *filename){
|
|||
|
||||
/*free the document */
|
||||
xmlFreeDoc(doc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
int i;
|
||||
Project *proj=new Project();
|
||||
OutputGenerator *gen=NULL;
|
||||
list<string> files;
|
||||
list<string>::iterator it;
|
||||
|
||||
LIBXML_TEST_VERSION
|
||||
|
||||
for(i=1;i<argc;i++){
|
||||
if (strcmp(argv[i],"--help")==0){
|
||||
fprintf(stderr,"%s: [--help] file1 file2...\nParses xml files generated by doxygen to output wrappers in a specified language.\n",argv[0]);
|
||||
fprintf(stderr,"%s: [--help] --output (c++) file1 file2...\nParses xml files generated by doxygen to output wrappers in a specified language.\n",argv[0]);
|
||||
return -1;
|
||||
}if (strcmp(argv[i],"--output")==0){
|
||||
i++;
|
||||
if (strcmp(argv[i],"c++")==0){
|
||||
gen=new CplusplusGenerator();
|
||||
}else if (strcmp(argv[i],"javascript")==0){
|
||||
gen=new JavascriptGenerator();
|
||||
}
|
||||
}else{
|
||||
if (parse_file(proj,argv[i])==-1)
|
||||
break;
|
||||
files.push_back(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (gen==NULL) {
|
||||
cerr<<"No output generator selected !"<<endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(it=files.begin();it!=files.end();it++){
|
||||
if (parse_file(proj,(*it).c_str())==-1){
|
||||
cerr<<"Parsing aborted."<<endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
proj->analyse();
|
||||
gen->generate(proj);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
tools/software-desc.cc
Normal file
40
tools/software-desc.cc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2013 Belledonne Communications SARL
|
||||
Simon Morlat (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "software-desc.hh"
|
||||
|
||||
Type Type::sStringType(Type::String);
|
||||
Type Type::sIntegerType(Type::Integer);
|
||||
Type Type::sVoidType(Type::Void);
|
||||
Type Type::sBooleanType(Type::Boolean);
|
||||
Type Type::sFloatType(Type::Float);
|
||||
std::map<string,Type*> Type::mTypes;
|
||||
const char *Type::sBasicTypeNames[]={
|
||||
"Void",
|
||||
"Boolean",
|
||||
"Integer",
|
||||
"Float",
|
||||
"String",
|
||||
"Enum",
|
||||
"Class",
|
||||
"Callback",
|
||||
"undef",
|
||||
"undef"
|
||||
};
|
||||
369
tools/software-desc.hh
Normal file
369
tools/software-desc.hh
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2013 Belledonne Communications SARL
|
||||
Simon Morlat (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef software_desc_hh
|
||||
#define software_desc_hh
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
using namespace::std;
|
||||
|
||||
|
||||
class Type{
|
||||
public:
|
||||
enum BasicType{
|
||||
Void,
|
||||
Boolean,
|
||||
Integer,
|
||||
Float,
|
||||
String,
|
||||
Enum,
|
||||
Class,
|
||||
Callback
|
||||
};
|
||||
static const char *sBasicTypeNames[];
|
||||
static Type* addType(BasicType bt, const string &name){
|
||||
Type* ret;
|
||||
if ((ret=mTypes[name])==0){
|
||||
//cout<<"Adding new "<<sBasicTypeNames[(int)bt]<<" type '"<<name<<"'"<<endl;
|
||||
ret=mTypes[name]=new Type(bt,name);
|
||||
}else if (bt!=Class){
|
||||
ret->mBasic=bt;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static Type *getType(const std::string &tname){
|
||||
if (strstr(tname.c_str(),"char")!=0 && strchr(tname.c_str(),'*')!=0){
|
||||
return &sStringType;
|
||||
}else if (tname.find("int")==0){
|
||||
return &sIntegerType;
|
||||
}else if (tname.find("float")==0){
|
||||
return &sFloatType;
|
||||
}else if (tname.find("bool_t")==0){
|
||||
return &sBooleanType;
|
||||
}else if (tname.find("void")!=string::npos){
|
||||
return &sVoidType;
|
||||
}else if (tname.find("enum")==0){
|
||||
return addType(Enum,tname.c_str()+strlen("enum "));
|
||||
}else{/*an object?*/
|
||||
|
||||
string tmp=tname;
|
||||
size_t pos;
|
||||
|
||||
/*really ugly and slow*/
|
||||
|
||||
pos=tmp.find('*');
|
||||
if (pos!=string::npos)
|
||||
tmp.erase(pos,1);
|
||||
|
||||
pos=tmp.find("const");
|
||||
if (pos!=string::npos)
|
||||
tmp.erase(pos,strlen("const"));
|
||||
|
||||
while ((pos=tmp.find(' '))!=string::npos){
|
||||
tmp.erase(pos,1);
|
||||
}
|
||||
return addType(Class,tmp);
|
||||
}
|
||||
cerr<<"Unhandled type name"<<tname<<endl;
|
||||
return NULL;
|
||||
}
|
||||
const string &getName()const{
|
||||
return mName;
|
||||
}
|
||||
BasicType getBasicType()const{
|
||||
return mBasic;
|
||||
}
|
||||
private:
|
||||
BasicType mBasic;
|
||||
string mName;
|
||||
Type(BasicType basic, const std::string &tname="") : mBasic(basic), mName(tname){
|
||||
}
|
||||
static Type sStringType;
|
||||
static Type sIntegerType;
|
||||
static Type sVoidType;
|
||||
static Type sBooleanType;
|
||||
static Type sFloatType;
|
||||
static std::map<string,Type*> mTypes;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Argument{
|
||||
public:
|
||||
Argument(Type *type, const string &argname, bool isConst, bool isPointer) : mType(type), mName(argname), mConst(isConst), mPointer(isPointer){
|
||||
if (!isPointer) mConst=false;
|
||||
}
|
||||
Type *getType()const{
|
||||
return mType;
|
||||
}
|
||||
bool isConst()const{
|
||||
return mConst;
|
||||
}
|
||||
const string &getName()const{
|
||||
return mName;
|
||||
}
|
||||
bool isPointer()const{
|
||||
return mPointer;
|
||||
}
|
||||
const string &getHelp()const{
|
||||
return mHelp;
|
||||
}
|
||||
void setHelp(const string &help){
|
||||
mHelp=help;
|
||||
}
|
||||
private:
|
||||
|
||||
Type *mType;
|
||||
string mName;
|
||||
string mHelp;
|
||||
bool mConst;
|
||||
bool mPointer;
|
||||
};
|
||||
|
||||
class Method{
|
||||
public:
|
||||
enum PropertyBehaviour{
|
||||
None,
|
||||
Read,
|
||||
Write
|
||||
};
|
||||
Method(const std::string &uid, Argument* return_arg, const std::string &name, const list<Argument*> &args, bool isConst, bool isStatic){
|
||||
mUid=uid;
|
||||
mReturn=return_arg;
|
||||
mName=name;
|
||||
mArgs=args;
|
||||
mConst=isConst;
|
||||
mStatic=isStatic;
|
||||
analyseProperties();
|
||||
}
|
||||
void setHelp(const std::string &help){
|
||||
mHelp=help;
|
||||
}
|
||||
Argument *getReturnArg()const{
|
||||
return mReturn;
|
||||
}
|
||||
const string &getName()const{
|
||||
return mName;
|
||||
}
|
||||
const list<Argument*> &getArgs()const {
|
||||
return mArgs;
|
||||
}
|
||||
bool isConst()const{
|
||||
return mConst;
|
||||
}
|
||||
bool isStatic()const{
|
||||
return mStatic;
|
||||
}
|
||||
const string &getHelp(){
|
||||
return mHelp;
|
||||
}
|
||||
PropertyBehaviour getPropertyBehaviour()const{
|
||||
return mPropertyBehaviour;
|
||||
}
|
||||
const string &getPropertyName()const{
|
||||
return mPropertyName;
|
||||
}
|
||||
private:
|
||||
void analyseProperties(){
|
||||
size_t enabled_pos;
|
||||
mPropertyBehaviour=None;
|
||||
|
||||
if (mName.find("get")==0 && mArgs.size()==0){
|
||||
mPropertyName=mName.substr(3,string::npos);
|
||||
if (!mPropertyName.empty()){
|
||||
mPropertyName[0]=tolower(mPropertyName[0]);
|
||||
mPropertyBehaviour=Read;
|
||||
}
|
||||
}else if (mName.find("enable")==0 && mArgs.size()==1){
|
||||
mPropertyName=mName.substr(6,string::npos);
|
||||
if (!mPropertyName.empty()){
|
||||
mPropertyName[0]=tolower(mPropertyName[0]);
|
||||
mPropertyBehaviour=Write;
|
||||
}
|
||||
}else if (mName.find("set")==0 && mArgs.size()==1){
|
||||
mPropertyName=mName.substr(3,string::npos);
|
||||
if (!mPropertyName.empty()){
|
||||
mPropertyName[0]=tolower(mPropertyName[0]);
|
||||
mPropertyBehaviour=Write;
|
||||
}
|
||||
}else if ((enabled_pos=mName.rfind("Enabled"))!=string::npos && mArgs.size()==0){
|
||||
size_t goodpos=mName.size()-7;
|
||||
if (enabled_pos==goodpos){
|
||||
mPropertyName=mName.substr(0,goodpos);
|
||||
if (!mPropertyName.empty()){
|
||||
mPropertyBehaviour=Read;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mPropertyBehaviour==None)
|
||||
mPropertyName="";
|
||||
}
|
||||
string mUid;
|
||||
Argument *mReturn;
|
||||
string mName;
|
||||
list<Argument*> mArgs;
|
||||
string mHelp;
|
||||
string mPropertyName; /*if it can be a property*/
|
||||
PropertyBehaviour mPropertyBehaviour;
|
||||
bool mConst;
|
||||
bool mStatic;
|
||||
};
|
||||
|
||||
class Property{
|
||||
public:
|
||||
enum Attribute{
|
||||
ReadOnly,
|
||||
ReadWrite
|
||||
};
|
||||
Property(Attribute attr, const string &name, Type *type, const string &help) : mAttr(attr), mName(name), mType(type), mHelp(help){
|
||||
}
|
||||
const string &getName()const{
|
||||
return mName;
|
||||
}
|
||||
const string &getHelp()const{
|
||||
return mHelp;
|
||||
}
|
||||
void setHelp(const string &help){
|
||||
mHelp=help;
|
||||
}
|
||||
Attribute getAttribute()const{
|
||||
return mAttr;
|
||||
}
|
||||
void setAttribute(Attribute attr){
|
||||
mAttr=attr;
|
||||
}
|
||||
Type* getType()const{
|
||||
return mType;
|
||||
}
|
||||
private:
|
||||
Attribute mAttr;
|
||||
string mName;
|
||||
Type *mType;
|
||||
string mHelp;
|
||||
};
|
||||
|
||||
/*actually a class or an enum*/
|
||||
class Class{
|
||||
public:
|
||||
Class(const std::string &name): mName(name){
|
||||
}
|
||||
Type::BasicType getType(){
|
||||
return Type::getType(mName)->getBasicType();
|
||||
}
|
||||
void addMethod(Method *method){
|
||||
if (mMethods.find(method->getName())==mMethods.end())
|
||||
mMethods.insert(make_pair(method->getName(),method));
|
||||
}
|
||||
void setHelp(const std::string &help){
|
||||
mHelp=help;
|
||||
}
|
||||
const list<Method*> getMethods()const{
|
||||
list<Method*> ret;
|
||||
map<string,Method*>::const_iterator it;
|
||||
for(it=mMethods.begin();it!=mMethods.end();++it){
|
||||
ret.push_back((*it).second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const string &getName()const{
|
||||
return mName;
|
||||
}
|
||||
const string &getHelp()const{
|
||||
return mHelp;
|
||||
}
|
||||
const list<Property*> getProperties(){
|
||||
list<Property*> ret;
|
||||
map<string,Property*>::const_iterator it;
|
||||
for(it=mProperties.begin();it!=mProperties.end();++it){
|
||||
ret.push_back((*it).second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void computeProperties(){
|
||||
map<string,Method*>::const_iterator it;
|
||||
Property *prop;
|
||||
for (it=mMethods.begin();it!=mMethods.end();++it){
|
||||
Method *m=(*it).second;
|
||||
if (m->getPropertyBehaviour()==Method::Read){
|
||||
prop=mProperties[m->getPropertyName()];
|
||||
if (prop==NULL){
|
||||
prop=new Property(Property::ReadOnly,m->getPropertyName(),m->getReturnArg()->getType(), m->getHelp());
|
||||
mProperties[m->getPropertyName()]=prop;
|
||||
}
|
||||
}else if (m->getPropertyBehaviour()==Method::Write){
|
||||
prop=mProperties[m->getPropertyName()];
|
||||
if (prop==NULL){
|
||||
prop=new Property(Property::ReadWrite,m->getPropertyName(),m->getArgs().front()->getType(), m->getHelp());
|
||||
mProperties[m->getPropertyName()]=prop;
|
||||
}else{
|
||||
prop->setHelp(m->getHelp());
|
||||
prop->setAttribute(Property::ReadWrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
map<string,Method*> mMethods;
|
||||
map<string,Property*> mProperties;
|
||||
string mName;
|
||||
string mHelp;
|
||||
};
|
||||
|
||||
class Project{
|
||||
public:
|
||||
Project(const string &name="wrapper") : mName(name){
|
||||
}
|
||||
Class *getClass(const std::string &name){
|
||||
Class *ret;
|
||||
if ((ret=mClasses[name])==NULL){
|
||||
ret=mClasses[name]=new Class(name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
list<Class*> getClasses()const{
|
||||
list<Class*> ret;
|
||||
map<string,Class*>::const_iterator it;
|
||||
for(it=mClasses.begin();it!=mClasses.end();++it){
|
||||
ret.push_back((*it).second);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const string &getName()const{
|
||||
return mName;
|
||||
}
|
||||
void analyse(){
|
||||
list<Class*> classes=getClasses();
|
||||
for_each(classes.begin(),classes.end(),mem_fun(&Class::computeProperties));
|
||||
}
|
||||
private:
|
||||
map<string,Class*> mClasses;
|
||||
string mName;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue