Четверг 02 Сентябрь 2004 22:41, Kim Woelders написал:

> >     1. The allocation on the stack around 16 kilobytes is not a god idea,
> > because stack was invented for function calls and recursion , but not for
> > storing data. And this could theoretically lead to a problem in general
> > case, if system cannot allocate such a big chunk on the stack.
>
> We may be using a bit more stack space than necessary, but I doubt this
> causes any problems in E in real life. This construction is used
> throughout E's parsing code and recursion is never very deep.
> It is also vastly faster and less error prone than allocating memory
> dynamically.
> I don't agree with the "storing data" issue. The stack is the perfect
> place to store (moderate amounts of) data temporarily.
>

Point taken. But i hope if i continue to write malloced code, it will be not 
count as an act of disobeying :-)

> > hopefully nothing,  but still this two functions word and fword are not
> > safe, scanf("%<num>n") is better, but it is not an easy tool for string
> > parsing. If somebody protected eesh from buffer smashing, then it is
> > fine, but still i'm suspicious in using word and fword anyway (and of
> > course i believe there is no suid binaries in disributions :-)).
>
> If word() or fword() are broken they should be fixed. The solution is
> not to introduce yet another string parsing function.
>

Agreed, but getword already there. 
I will look at this functions, hopefully do something. 

>
> Finally, in case you haven't been discouraged entirely, one more thing.
> Please do not use C++ style "//" comments. I believe there are still
> compilers out there which don't like that.
>
> /Kim
>

So then i regenerate my patch, here it is:

--- ./etalon/e16/e/src/E.h      2004-08-31 21:24:39.000000000 +0400
+++ ./hacked/e16/e/src/E.h      2004-09-07 11:26:12.433520592 +0400
@@ -2083,7 +2110,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);
+char               *getword(char *s,int num)    ;
 void                word(const char *s, int num, char *wd);
 int                 canread(const char *s);
 int                 canwrite(const char *s);

--- ./etalon/e16/e/src/file.c   2004-07-13 03:33:15.000000000 +0400
+++ file.c      2004-09-07 11:38:43.320368440 +0400
@@ -510,74 +510,155 @@
    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  
+ */
+char *
+getword(const char *s, int num)
+{
+   int cnt              = 1                     ;
+   
+   ptrdiff_t char_count = 0                     ;
+   
+   char *start                  = NULL          ; 
+   char *word                   = NULL          ;
+   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 char quota_sym = '"'                   ;
+
+   EDBUG(9,"getword")                           ;
 
-   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_idP47&alloc_id808&op=click
_______________________________________________
enlightenment-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to