]> git.sesse.net Git - vlc/commitdiff
* Documentation belongs to the .h, step 1
authorClément Stenac <zorglub@videolan.org>
Sun, 19 Nov 2006 14:37:04 +0000 (14:37 +0000)
committerClément Stenac <zorglub@videolan.org>
Sun, 19 Nov 2006 14:37:04 +0000 (14:37 +0000)
* Unexported a few internal functions
  (playlist_ItemDelete, playlist_ThreadCreate, playlist_ThreadDestroy)
* Remove playlist_AddSDModules and merge its features into ServicesDiscoveryAdd
* Fix a bug in signaling of node destruction (fixes Qt source selector assertion failures)
* Disable unused generic devices probe code

include/vlc_devices.h
include/vlc_playlist.h
include/vlc_symbols.h
src/libvlc-common.c
src/misc/devices.c
src/playlist/control.c
src/playlist/item.c
src/playlist/loadsave.c
src/playlist/playlist_internal.h
src/playlist/services_discovery.c
src/playlist/tree.c

index f503a4d90c3d00007a0002655f1ec03c257629e7..d3c98717fd7d739c4da3f10632bde7b66de3da63 100644 (file)
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
-
+#if 0
 #ifndef _VLC_DEVICES_H
 #define _VLC_DEVICES_H 1
 
@@ -56,7 +56,9 @@ struct device_probe_t
     void      ( *pf_run )    ( device_probe_t * );  /** Run function */
 };
 
-static inline void device_GetDVD()
-{}
+static inline void device_GetDVD(void)
+{
+}
 
 #endif
+#endif
index 272e0f3ec7dcdc45e5da495830ef502fc471b8d3..0d9d26a3e16fdcc799a7d7b8dca5b4300e3fad22 100644 (file)
@@ -31,6 +31,7 @@
 
 TYPEDEF_ARRAY(playlist_item_t*, playlist_item_array_t);
 TYPEDEF_ARRAY(input_item_t*, input_item_array_t);
+
 /**
  * \file
  * This file contain structures and function prototypes related
@@ -126,16 +127,13 @@ struct playlist_export_t
 /** playlist item / node */
 struct playlist_item_t
 {
-    input_item_t           *p_input;    /**< input item descriptor */
-
-    /* Tree specific fields */
-    int                    i_children;  /**< Number of children
-                                             -1 if not a node */
+    input_item_t           *p_input;    /**< Linked input item */
+    /** Number of children, -1 if not a node */
+    int                    i_children;
     playlist_item_t      **pp_children; /**< Children nodes/items */
     playlist_item_t       *p_parent;    /**< Item parent */
 
     int                    i_id;        /**< Playlist item specific id */
-
     uint8_t                i_flags;     /**< Flags */
 };
 
@@ -265,11 +263,6 @@ struct playlist_add_t
  * Prototypes
  *****************************************************************************/
 
-/* Global thread */
-#define playlist_ThreadCreate(a) __playlist_ThreadCreate(VLC_OBJECT(a))
-void        __playlist_ThreadCreate   ( vlc_object_t * );
-int           playlist_ThreadDestroy  ( playlist_t * );
-
 /* Helpers */
 #define PL_LOCK vlc_mutex_lock( &p_playlist->object_lock );
 #define PL_UNLOCK vlc_mutex_unlock( &p_playlist->object_lock );
@@ -292,19 +285,38 @@ static inline playlist_t *__pl_Yield( vlc_object_t *p_this )
 #define playlist_Prev(p) playlist_Control(p,PLAYLIST_SKIP, VLC_FALSE, -1)
 #define playlist_Skip(p,i) playlist_Control(p,PLAYLIST_SKIP, VLC_FALSE,  i)
 
-VLC_EXPORT( int, playlist_Control, ( playlist_t *, int, vlc_bool_t, ...  ) );
+/**
+ * Do a playlist action.
+ * If there is something in the playlist then you can do playlist actions.
+ * Possible queries are listed in vlc_common.h
+ * \param p_playlist the playlist to do the command on
+ * \param i_query the command to do
+ * \param b_locked TRUE if playlist is locked when entering this function
+ * \param variable number of arguments
+ * \return VLC_SUCCESS or an error
+ */
+VLC_EXPORT( int, playlist_Control, ( playlist_t *p_playlist, int i_query, vlc_bool_t b_locked, ...  ) );
 
+/** Clear the playlist
+ * \param b_locked TRUE if playlist is locked when entering this function
+ */
 VLC_EXPORT( void,  playlist_Clear, ( playlist_t *, vlc_bool_t ) );
 
+/** Enqueue an input item for preparsing */
 VLC_EXPORT( int, playlist_PreparseEnqueue, (playlist_t *, input_item_t *) );
+
+/** Enqueue a playlist item and all of its children if any for preparsing */
 VLC_EXPORT( int, playlist_PreparseEnqueueItem, (playlist_t *, playlist_item_t *) );
+/** Request the art for an input item to be fetched */
 VLC_EXPORT( int, playlist_AskForArtEnqueue, (playlist_t *, input_item_t *) );
 
-/* Services discovery */
+/********************** Services discovery ***********************/
 
+/** Add a list of comma-separated service discovery modules */
 VLC_EXPORT( int, playlist_ServicesDiscoveryAdd, (playlist_t *, const char *));
+/** Remove a services discovery module by name */
 VLC_EXPORT( int, playlist_ServicesDiscoveryRemove, (playlist_t *, const char *));
-VLC_EXPORT( int, playlist_AddSDModules, (playlist_t *, char *));
+/** Check whether a given SD is loaded */
 VLC_EXPORT( vlc_bool_t, playlist_IsServicesDiscoveryLoaded, ( playlist_t *,const char *));
 
 /* Playlist sorting */
@@ -312,8 +324,15 @@ VLC_EXPORT( int,  playlist_TreeMove, ( playlist_t *, playlist_item_t *, playlist
 VLC_EXPORT( int,  playlist_NodeSort, ( playlist_t *, playlist_item_t *,int, int ) );
 VLC_EXPORT( int,  playlist_RecursiveNodeSort, ( playlist_t *, playlist_item_t *,int, int ) );
 
-/* Save a playlist file */
-VLC_EXPORT( int,  playlist_Export, ( playlist_t *, const char *, playlist_item_t *, const char * ) );
+/**
+ * Export a node of the playlist to a certain type of playlistfile
+ * \param p_playlist the playlist to export
+ * \param psz_filename the location where the exported file will be saved
+ * \param p_export_root the root node to export
+ * \param psz_type the type of playlist file to create (m3u, pls, ..)
+ * \return VLC_SUCCESS on success
+ */
+VLC_EXPORT( int,  playlist_Export, ( playlist_t *p_playlist, const char *psz_name, playlist_item_t *p_export_root, const char *psz_type ) );
 
 /********************************************************
  * Item management
@@ -323,25 +342,19 @@ VLC_EXPORT( int,  playlist_Export, ( playlist_t *, const char *, playlist_item_t
 
 VLC_EXPORT( playlist_item_t* , playlist_ItemNewWithType, ( vlc_object_t *,const char *,const char *, int , const char *const *, int, int) );
 
-#define playlist_ItemNew( a , b, c ) __playlist_ItemNew(VLC_OBJECT(a) , b , c )
 /** Create a new item, without adding it to the playlist
  * \param p_obj a vlc object (anyone will do)
  * \param psz_uri the mrl of the item
  * \param psz_name a text giving a name or description of the item
  * \return the new item or NULL on failure
  */
-static inline playlist_item_t * __playlist_ItemNew( vlc_object_t *p_obj,
-                                     const char *psz_uri, const char *psz_name )
-{
-    /* 0 = ITEM_TYPE_UNKNOWN */
-    return playlist_ItemNewWithType( p_obj, psz_uri,  psz_name, 0, NULL, -1,0);
-}
+#define playlist_ItemNew( a , b, c ) \
+    playlist_ItemNewWithType( VLC_OBJECT(a) , b , c, 0, NULL, -1, 0 )
 
 #define playlist_ItemNewFromInput(a,b) __playlist_ItemNewFromInput(VLC_OBJECT(a),b)
 VLC_EXPORT( playlist_item_t *, __playlist_ItemNewFromInput, ( vlc_object_t *p_obj,input_item_t *p_input ) );
 
 /*************************** Item deletion **************************/
-VLC_EXPORT( int, playlist_ItemDelete, ( playlist_item_t * ) );
 VLC_EXPORT( int,  playlist_DeleteFromInput, ( playlist_t *, int, vlc_bool_t ) );
 
 /*************************** Item fields accessors **************************/
index 28730bfbfa9498afcc196d722f5e53342fd03863..001f017ec857c8938d1f48f98746c5a3131eb38c 100644 (file)
@@ -256,19 +256,19 @@ struct module_symbols_t
     void (*__vlc_object_release_inner) (vlc_object_t *);
     vlc_list_t * (*__vlc_list_find_inner) (vlc_object_t *, int, int);
     void (*vlc_list_release_inner) (vlc_list_t *);
-    int (*playlist_Control_inner) (playlist_t *, int, vlc_bool_t, ...);
+    int (*playlist_Control_inner) (playlist_t *p_playlist, int i_query, vlc_bool_t b_locked, ...);
     void *playlist_LockControl_deprecated;
     void (*playlist_Clear_inner) (playlist_t *, vlc_bool_t);
     void *playlist_LockClear_deprecated;
     int (*playlist_PreparseEnqueue_inner) (playlist_t *, input_item_t *);
     int (*playlist_ServicesDiscoveryAdd_inner) (playlist_t *, const char *);
     int (*playlist_ServicesDiscoveryRemove_inner) (playlist_t *, const char *);
-    int (*playlist_AddSDModules_inner) (playlist_t *, char *);
+    void *playlist_AddSDModules_deprecated;
     vlc_bool_t (*playlist_IsServicesDiscoveryLoaded_inner) (playlist_t *,const char *);
     void *__playlist_ItemNew_deprecated;
     void *__playlist_ItemCopy_deprecated;
     playlist_item_t* (*playlist_ItemNewWithType_inner) (vlc_object_t *,const char *,const char *, int , const char *const *, int, int);
-    int (*playlist_ItemDelete_inner) (playlist_item_t *);
+    void *playlist_ItemDelete_deprecated;
     void *playlist_ItemAddParent_deprecated;
     void *playlist_CopyParents_deprecated;
     int (*playlist_ItemSetName_inner) (playlist_item_t *, const char *);
@@ -313,7 +313,7 @@ struct module_symbols_t
     int (*playlist_NodeSort_inner) (playlist_t *, playlist_item_t *,int, int);
     int (*playlist_RecursiveNodeSort_inner) (playlist_t *, playlist_item_t *,int, int);
     void *playlist_Import_deprecated;
-    int (*playlist_Export_inner) (playlist_t *, const char *, playlist_item_t *, const char *);
+    int (*playlist_Export_inner) (playlist_t *p_playlist, const char *psz_name, playlist_item_t *p_export_root, const char *psz_type);
     spu_t * (*__spu_Create_inner) (vlc_object_t *);
     int (*spu_Init_inner) (spu_t *);
     void (*spu_Destroy_inner) (spu_t *);
@@ -797,10 +797,8 @@ struct module_symbols_t
 #  define playlist_PreparseEnqueue (p_symbols)->playlist_PreparseEnqueue_inner
 #  define playlist_ServicesDiscoveryAdd (p_symbols)->playlist_ServicesDiscoveryAdd_inner
 #  define playlist_ServicesDiscoveryRemove (p_symbols)->playlist_ServicesDiscoveryRemove_inner
-#  define playlist_AddSDModules (p_symbols)->playlist_AddSDModules_inner
 #  define playlist_IsServicesDiscoveryLoaded (p_symbols)->playlist_IsServicesDiscoveryLoaded_inner
 #  define playlist_ItemNewWithType (p_symbols)->playlist_ItemNewWithType_inner
-#  define playlist_ItemDelete (p_symbols)->playlist_ItemDelete_inner
 #  define playlist_ItemSetName (p_symbols)->playlist_ItemSetName_inner
 #  define playlist_NodeCreate (p_symbols)->playlist_NodeCreate_inner
 #  define playlist_NodeAppend (p_symbols)->playlist_NodeAppend_inner
@@ -1269,10 +1267,8 @@ struct module_symbols_t
     ((p_symbols)->playlist_PreparseEnqueue_inner) = playlist_PreparseEnqueue; \
     ((p_symbols)->playlist_ServicesDiscoveryAdd_inner) = playlist_ServicesDiscoveryAdd; \
     ((p_symbols)->playlist_ServicesDiscoveryRemove_inner) = playlist_ServicesDiscoveryRemove; \
-    ((p_symbols)->playlist_AddSDModules_inner) = playlist_AddSDModules; \
     ((p_symbols)->playlist_IsServicesDiscoveryLoaded_inner) = playlist_IsServicesDiscoveryLoaded; \
     ((p_symbols)->playlist_ItemNewWithType_inner) = playlist_ItemNewWithType; \
-    ((p_symbols)->playlist_ItemDelete_inner) = playlist_ItemDelete; \
     ((p_symbols)->playlist_ItemSetName_inner) = playlist_ItemSetName; \
     ((p_symbols)->playlist_NodeCreate_inner) = playlist_NodeCreate; \
     ((p_symbols)->playlist_NodeAppend_inner) = playlist_NodeAppend; \
@@ -1508,8 +1504,10 @@ struct module_symbols_t
     (p_symbols)->vlc_input_item_AddInfo_deprecated = NULL; \
     (p_symbols)->playlist_LockControl_deprecated = NULL; \
     (p_symbols)->playlist_LockClear_deprecated = NULL; \
+    (p_symbols)->playlist_AddSDModules_deprecated = NULL; \
     (p_symbols)->__playlist_ItemNew_deprecated = NULL; \
     (p_symbols)->__playlist_ItemCopy_deprecated = NULL; \
+    (p_symbols)->playlist_ItemDelete_deprecated = NULL; \
     (p_symbols)->playlist_ItemAddParent_deprecated = NULL; \
     (p_symbols)->playlist_CopyParents_deprecated = NULL; \
     (p_symbols)->playlist_ItemSetDuration_deprecated = NULL; \
index bb70edf575de5974a541a2b19e2c4a177859d5c8..3a8f3d01d4f300dce8af0ff3fcf68875f4ff5d7d 100644 (file)
@@ -88,6 +88,8 @@
 
 #include "libvlc.h"
 
+#include "playlist/playlist_internal.h"
+
 /*****************************************************************************
  * The evil global variable. We handle it with care, don't worry.
  *****************************************************************************/
@@ -676,7 +678,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
     if( psz_modules && *psz_modules )
     {
         /* Add service discovery modules */
-        playlist_AddSDModules( p_playlist, psz_modules );
+        playlist_ServicesDiscoveryAdd( p_playlist, psz_modules );
     }
     if( psz_modules ) free( psz_modules );
 
index 3d8f6be141122413919e661b899f09cab45f7d90..9a146cb732b5367b26788f62f00b1786a120028a 100644 (file)
@@ -21,6 +21,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+#if 0
+
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
@@ -50,3 +52,5 @@ void devices_ProbeCreate( vlc_object_t *p_this )
 
     p_this->p_libvlc_global->p_probe = p_probe;
 }
+
+#endif
index 2b518c6b1b11615846690b66fcc977da6a66b57a..4f2a383bebc1f7f725929a6fa02354aef466edaa 100644 (file)
@@ -38,17 +38,6 @@ static void PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );
  * Playlist control
  *****************************************************************************/
 
-/**
- * Do a playlist action.
- * If there is something in the playlist then you can do playlist actions.
- * Should be entered with playlist lock. See include/vlc_playlist.h for
- * possible queries
- *
- * \param p_playlist the playlist to do the command on
- * \param i_query the command to do
- * \param variable number of arguments
- * \return VLC_SUCCESS or an error
- */
 int playlist_Control( playlist_t * p_playlist, int i_query, vlc_bool_t b_locked, ... )
 {
     va_list args;
index 720bcbced303ee5db26661fc7d85f02c28df881f..86a26f8316d47d1d2e567d703b989cdde5da2d5b 100644 (file)
@@ -123,7 +123,6 @@ int playlist_DeleteFromInput( playlist_t *p_playlist, int i_input_id,
     return VLC_SUCCESS;
 }
 
-/** Clear the playlist */
 void playlist_Clear( playlist_t * p_playlist, vlc_bool_t b_locked )
 {
     if( !b_locked ) PL_LOCK;
index 6ec5ccfade05ab3310967faabe6a6fa8d666621a..1800287f3718296a557c91908359cbace9386301 100644 (file)
 #include "charset.h"
 #include <errno.h>
 
-/**
- * Export a node of the playlist to a certain type of playlistfile
- *
- * \param p_playlist the playlist to export
- * \param psz_filename the location where the exported file will be saved
- * \param p_export_root the root node to export
- * \param psz_type the type of playlist file to create.
- * \return VLC_SUCCESS on success
- */
 int playlist_Export( playlist_t * p_playlist, const char *psz_filename ,
                      playlist_item_t *p_export_root,const char *psz_type )
 {
index 03f61c63482f2d6b8e05ad8aaa15930113ddae13..ad4e03bd187dd709ff22b58ff1cde459ecc0d167 100644 (file)
@@ -60,6 +60,11 @@ struct playlist_fetcher_t
  * Prototypes
  *****************************************************************************/
 
+/* Global thread */
+#define playlist_ThreadCreate(a) __playlist_ThreadCreate(VLC_OBJECT(a))
+void        __playlist_ThreadCreate   ( vlc_object_t * );
+int           playlist_ThreadDestroy  ( playlist_t * );
+
 /* Creation/Deletion */
 playlist_t *playlist_Create   ( vlc_object_t * );
 void        playlist_Destroy  ( playlist_t * );
@@ -100,13 +105,14 @@ playlist_item_t *playlist_GetLastLeaf( playlist_t *p_playlist,
                                     playlist_item_t *p_root );
 
 int playlist_DeleteFromItemId( playlist_t*, int );
+int playlist_ItemDelete ( playlist_item_t * );
 
 /**
  * @}
  */
 
 #define PLAYLIST_DEBUG 1
-//#undef PLAYLIST_DEBUG
+//#undef PLAYLIST_DEBUG2
 
 #ifdef PLAYLIST_DEBUG
  #define PL_DEBUG( msg, args... ) msg_Dbg( p_playlist, msg, ## args )
index cf3ad5768e85c4a9b93502164fd85e58382effff..a14c85381793d8942c13ba891b599c6cfb971121 100644 (file)
 #include "vlc_playlist.h"
 #include "playlist_internal.h"
 
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-
 static void RunSD( services_discovery_t *p_sd );
 
-
-/***************************************************************************
-***************************************************************************/
-
-int playlist_ServicesDiscoveryAdd( playlist_t *p_playlist,
-                                   const char *psz_module )
+int playlist_ServicesDiscoveryAdd( playlist_t *p_playlist,  const char *psz_modules )
 {
-    services_discovery_t *p_sd;
-
-    p_sd = vlc_object_create( p_playlist, VLC_OBJECT_SD );
-    p_sd->pf_run = NULL;
-
-    p_sd->p_module = module_Need( p_sd, "services_discovery", psz_module, 0 );
-
-    if( p_sd->p_module == NULL )
+    if( psz_modules && *psz_modules )
     {
-        msg_Err( p_playlist, "no suitable services discovery module" );
-        vlc_object_destroy( p_sd );
-        return VLC_EGENERIC;
-    }
-
-    p_sd->psz_module = strdup( psz_module );
-    p_sd->b_die = VLC_FALSE;
-
-    vlc_mutex_lock( &p_playlist->object_lock );
-
-    INSERT_ELEM( p_playlist->pp_sds, p_playlist->i_sds, p_playlist->i_sds,
-                 p_sd );
+        char *psz_parser = psz_modules;
+        char *psz_next;
 
-    vlc_mutex_unlock( &p_playlist->object_lock );
+        while( psz_parser && *psz_parser )
+        {
+            while( *psz_parser == ' ' || *psz_parser == ':' || *psz_parser == ',' )
+                psz_parser++;
 
-    if( !p_sd->pf_run ) return VLC_SUCCESS;
+            if( (psz_next = strchr( psz_parser, ':' ) ) )
+                *psz_next++ = '\0';
 
-    if( vlc_thread_create( p_sd, "services_discovery", RunSD,
-                           VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
-    {
-        msg_Err( p_sd, "cannot create services discovery thread" );
-        vlc_object_destroy( p_sd );
-        return VLC_EGENERIC;
+            if( *psz_parser == '\0' )
+                break;
+            fprintf(stderr,"Add %s\n", psz_parser);
+            /* Perform the addition */
+            {
+                services_discovery_t *p_sd = vlc_object_create( p_playlist,
+                                                                VLC_OBJECT_SD );
+                p_sd->pf_run = NULL;
+                p_sd->p_module = module_Need( p_sd, "services_discovery", psz_parser, 0 );
+
+                if( p_sd->p_module == NULL )
+                {
+                    msg_Err( p_playlist, "no suitable services discovery module" );
+                    vlc_object_destroy( p_sd );
+                    return VLC_EGENERIC;
+                }
+                p_sd->psz_module = strdup( psz_parser );
+                p_sd->b_die = VLC_FALSE;
+
+                PL_LOCK;
+                TAB_APPEND( p_playlist->i_sds, p_playlist->pp_sds, p_sd );
+                PL_UNLOCK;
+
+                if( !p_sd->pf_run ) {
+                    psz_parser = psz_next;
+                    continue;
+                }
+
+                if( vlc_thread_create( p_sd, "services_discovery", RunSD,
+                                       VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
+                {
+                    msg_Err( p_sd, "cannot create services discovery thread" );
+                    vlc_object_destroy( p_sd );
+                    return VLC_EGENERIC;
+                }
+            }
+            psz_parser = psz_next;
+        }
     }
-
-
     return VLC_SUCCESS;
 }
 
@@ -132,42 +140,6 @@ vlc_bool_t playlist_IsServicesDiscoveryLoaded( playlist_t * p_playlist,
     return VLC_FALSE;
 }
 
-
-/**
- * Load all service discovery modules in a string
- *
- * \param p_playlist the playlist
- * \param psz_modules a list of modules separated by commads
- * return VLC_SUCCESS or an error
- */
-int playlist_AddSDModules( playlist_t *p_playlist, char *psz_modules )
-{
-    if( psz_modules && *psz_modules )
-    {
-        char *psz_parser = psz_modules;
-        char *psz_next;
-
-        while( psz_parser && *psz_parser )
-        {
-            while( *psz_parser == ' ' || *psz_parser == ':' )
-                psz_parser++;
-
-            if( (psz_next = strchr( psz_parser, ':' ) ) )
-                *psz_next++ = '\0';
-
-            if( *psz_parser == '\0' )
-            {
-                break;
-            }
-
-            playlist_ServicesDiscoveryAdd( p_playlist, psz_parser );
-
-            psz_parser = psz_next;
-        }
-    }
-    return VLC_SUCCESS;
-}
-
 static void RunSD( services_discovery_t *p_sd )
 {
     p_sd->pf_run( p_sd );
index fe4f70abe7ec529d302052f303b31b07bb04d0ce..d1e7f57b129b5face94a06ed1cd19ed0d5acb8d3 100644 (file)
@@ -68,7 +68,6 @@ playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist, const char *psz_n
 
     if( p_parent != NULL )
         playlist_NodeAppend( p_playlist, p_item, p_parent );
-
     playlist_SendAddNotify( p_playlist, p_item->i_id,
                             p_parent ? p_parent->i_id : -1 );
     return p_item;
@@ -150,7 +149,7 @@ int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
     else
     {
         int i;
-        var_SetInteger( p_playlist, "item-deleted", p_root->p_input->i_id );
+        var_SetInteger( p_playlist, "item-deleted", p_root->i_id );
         ARRAY_BSEARCH( p_playlist->all_items, ->p_input->i_id, int,
                        p_root->p_input->i_id, i );
         if( i != -1 )