Good day, everybody !

These two patches replace broken getword function in file.c with the not 
broken one (I hope). Also i made small warkaround about one bug, and i submit 
another patch later, but i need this function, so it will be really cool, if 
somebody merge these patches to the CVS.
Thank you in advance.

-- 
With best regards,
Vadik Mironov                           
                                        <[EMAIL PROTECTED]>

--- ./e/etalon/e16/e/src/E.h    2004-08-31 21:24:39.000000000 +0400
+++ ./e/hacked/e16/e/src/E.h    2004-09-01 12:00:40.485221968 +0400
@@ -2083,7 +2083,7 @@
 char               *usershell(int uid);
 const char         *atword(const char *s, int num);
 const char         *atchar(const char *s, char c);
-char               *getword(char *s, int num);
+unsigned char      *getword(unsigned char *s,int num);
 void                word(const char *s, int num, char *wd);
 int                 canread(const char *s);
 int                 canwrite(const char *s);



--- ./e/etalon/e16/e/src/file.c 2004-07-13 03:33:15.000000000 +0400
+++ ./e/hacked/e16/e/src/file.c 2004-09-01 12:03:04.695298704 +0400
@@ -510,74 +510,153 @@
    EDBUG_RETURN(NULL);
 }
 
-char               *
-getword(char *s, int num)
-{
+/**
+ * Search for a [num]-th word in a string s and return it in
+ * allocated buffer. 
+ *
+ * Parameters :
+ *   s    - pointer to a null terminating string.
+ *         Punctuation signs treats as whitespaces.
+ *   num  - number of a token to search.
+ *
+ * Return value :
+ *   NULL - if (num < 1) or (num > number of tokens in s)
+ *          or if s contained unquoted symbols other than
+ *          spaces, digits and symbols.
+ *   Otherwise, pointer to null terminated string returned.
+ *   WARNING : Caller must free the buffer.
+ *
+ * Example : " {..\" Alice \" wants more \"cookies4 grandma \"" 
+ *   Token 1 =  Alice 
+ *   Token 2 = wants
+ *   Token 3 = more
+ *   Token 4 = cookies4 grandma  
+ */
+unsigned char *
+getword(unsigned char *s, int num)
+{
+   int cnt              = 1                     ;
+   
+   ptrdiff_t char_count = 0                     ;
+   
+   unsigned char *start          = NULL         ; 
+   unsigned char *word           = NULL         ;
+   unsigned char *tmp_copy       = NULL         ;
 
-   /* *********FIXME**************
-    * This function is broken but it isn't in use so I'll fix it later
-    * (DO NOT USE UNTIL FIXED
-    */
-   int                 cnt, i;
-   char               *start, *finish, *ss, *w;
-   char               *wd = NULL;
+   const unsigned char quota_sym = '"'          ;
 
-   EDBUG(9, "getword");
    if (!s)
-      EDBUG_RETURN(NULL);
-   if (!wd)
-      EDBUG_RETURN(NULL);
+   {   
+        goto fail                               ;
+   }
+   
+   //counting from 1, negative index is mistake
    if (num <= 0)
-     {
-       *wd = 0;
-       EDBUG_RETURN(NULL);
-     }
-   cnt = 0;
-   i = 0;
-   start = NULL;
-   finish = NULL;
-   ss = NULL;
-   w = wd;
-
-   while (s[i])
-     {
-       if ((cnt == num) && ((s[i] == ' ') || (s[i] == '\t')))
-         {
-            finish = &s[i];
-            break;
-         }
-       if ((s[i] != ' ') && (s[i] != '\t'))
-         {
-            if (i == 0)
-              {
-                 cnt++;
-                 if (cnt == num)
-                    start = &s[i];
-              }
-            else if ((s[i - 1] == ' ') || (s[i - 1] == '\t'))
-              {
-                 cnt++;
-                 if (cnt == num)
-                    start = &s[i];
-              }
-         }
-       i++;
-     }
-   if (cnt == num)
-     {
-       if ((start) && (finish))
-         {
-            for (ss = start; ss < finish; ss++)
-               *wd++ = *ss;
-         }
-       else if (start)
-         {
-            for (ss = start; *ss != 0; ss++)
-               *wd++ = *ss;
-         }
-       *wd = 0;
-     }
-   EDBUG_RETURN(wd);
+   {
+        goto fail                               ;
+   }
+   
+   //skip all whitespaces at first
+   //except double quotas since they are meaningful
+   //also let us ignore other garbage
+   while(!isalnum(*s) && quota_sym != *s)
+   {
+       s++                                      ;
+   }
+       
+   //main cycle till the end
+   while ('\0'!=*s)
+   {
+       //we are standing at the start of quotes
+       if (quota_sym == *s)
+       {
+           //step over quota
+           s++                                  ;
+           //save start in case of word
+           if(cnt == num)
+           {           
+               start = s                        ;
+           }
+           //it is possible to write inside quotes any trash
+           //even bells and whistles :-)
+           while (quota_sym != *s)
+           {                                        
+               //only one quote sign                                         
+               if ('\0' == *s)                             
+               {                        
+                   goto fail                    ;  
+               }                
+               s++                              ;
+           }
+
+           if (cnt == num)
+           {
+               char_count = s - start           ;
+               //so far we have start offset and char count
+               break                            ;
+           }
+           //quotation ended
+           cnt++                                ;
+       } else if (isalnum(*s))
+       {
+           if(cnt == num)
+           {
+               start = s                        ;
+           }
+           //go through word
+           while (isalnum(*s))
+           {
+               s++                              ;            
+           }
+           //we found word
+           //note: it can be followed by any crap
+           if (cnt == num)
+           {
+               char_count = s - start           ;
+               break                            ;
+           }
+           
+           //word must be followed by space
+           if (!isspace(*s) && !ispunct(*s))
+           {
+               goto fail                        ;
+           }
+           //word ended
+           cnt++                                ;
+           //return at the end of the word
+           s--                                  ;
+       } else if (isspace(*s) || ispunct(*s))
+       {
+           //just ignoring spaces
+       } else
+       {
+           goto fail                            ;
+       }
+       s++                                      ; 
+   }
+
+   if (start==NULL)
+   {
+       //avoid allocation
+       goto fail                                ;
+   }
+   //at this point we found the WORD
+   tmp_copy = word = (unsigned char *)Emalloc((sizeof(char)*char_count) + 1);
+   if(NULL==tmp_copy)
+   {
+       goto fail                                ;
+   }
+   while (0<= --char_count)
+   {
+       *tmp_copy++ = *start++                   ;
+   }
+   *(tmp_copy++) = '\0'                         ;
+   goto success                                 ;
+       
+success :
+   EDBUG_RETURN(word)                           ;  
+fail :
+   EDBUG_RETURN(NULL)                           ;
 }
 
 void



-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=5047&alloc_id=10808&op=click
_______________________________________________
enlightenment-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to