Back to index

glibc  2.9
tst-regex2.c
Go to the documentation of this file.
00001 #include <fcntl.h>
00002 #include <locale.h>
00003 #include <regex.h>
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include <sys/stat.h>
00008 #include <time.h>
00009 #include <unistd.h>
00010 
00011 #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
00012 static clockid_t cl;
00013 static int use_clock;
00014 #endif
00015 
00016 static int
00017 do_test (void)
00018 {
00019 #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
00020 # if _POSIX_CPUTIME == 0
00021   if (sysconf (_SC_CPUTIME) < 0)
00022     use_clock = 0;
00023   else
00024 # endif
00025     /* See whether we can use the CPU clock.  */
00026     use_clock = clock_getcpuclockid (0, &cl) == 0;
00027 #endif
00028 
00029   static const char *pat[] = {
00030     ".?.?.?.?.?.?.?Log\\.13",
00031     "(.?)(.?)(.?)(.?)(.?)(.?)(.?)Log\\.13",
00032     "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))"
00033     "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))"
00034     "((((((((((.?))))))))))Log\\.13" };
00035 
00036   int fd = open ("../ChangeLog.14", O_RDONLY);
00037   if (fd < 0)
00038     {
00039       printf ("Couldn't open ChangeLog.14: %m\n");
00040       return 1;
00041     }
00042 
00043   struct stat64 st;
00044   if (fstat64 (fd, &st) < 0)
00045     {
00046       printf ("Couldn't fstat ChangeLog.14: %m\n");
00047       return 1;
00048     }
00049 
00050   char *buf = malloc (st.st_size + 1);
00051   if (buf == NULL)
00052     {
00053       printf ("Couldn't allocate buffer: %m\n");
00054       return 1;
00055     }
00056 
00057   if (read (fd, buf, st.st_size) != (ssize_t) st.st_size)
00058     {
00059       puts ("Couldn't read ChangeLog.14");
00060       return 1;
00061     }
00062 
00063   close (fd);
00064   buf[st.st_size] = '\0';
00065 
00066   setlocale (LC_ALL, "de_DE.UTF-8");
00067 
00068   char *string = buf;
00069   size_t len = st.st_size;
00070 
00071 #ifndef WHOLE_FILE_TIMING
00072   /* Don't search the whole file normally, it takes too long.  */
00073   if (len > 500000 + 64)
00074     {
00075       string += 500000;
00076       len -= 500000;
00077     }
00078 #endif
00079 
00080   for (int testno = 0; testno < 4; ++testno)
00081     for (int i = 0; i < sizeof (pat) / sizeof (pat[0]); ++i)
00082       {
00083        printf ("test %d pattern %d", testno, i);
00084 
00085        regex_t rbuf;
00086        struct re_pattern_buffer rpbuf;
00087        int err;
00088        if (testno < 2)
00089          {
00090            err = regcomp (&rbuf, pat[i],
00091                         REG_EXTENDED | (testno ? REG_NOSUB : 0));
00092            if (err != 0)
00093              {
00094               putchar ('\n');
00095               char errstr[300];
00096               regerror (err, &rbuf, errstr, sizeof (errstr));
00097               puts (errstr);
00098               return err;
00099              }
00100          }
00101        else
00102          {
00103            re_set_syntax (RE_SYNTAX_POSIX_EGREP
00104                         | (testno == 3 ? RE_NO_SUB : 0));
00105 
00106            memset (&rpbuf, 0, sizeof (rpbuf));
00107            const char *s = re_compile_pattern (pat[i], strlen (pat[i]),
00108                                           &rpbuf);
00109            if (s != NULL)
00110              {
00111               printf ("\n%s\n", s);
00112               return 1;
00113              }
00114 
00115            /* Just so that this can be tested with earlier glibc as well.  */
00116            if (testno == 3)
00117              rpbuf.no_sub = 1;
00118          }
00119 
00120 #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
00121       struct timespec start, stop;
00122       if (use_clock)
00123        use_clock = clock_gettime (cl, &start) == 0;
00124 #endif
00125 
00126       if (testno < 2)
00127        {
00128          regmatch_t pmatch[71];
00129          err = regexec (&rbuf, string, 71, pmatch, 0);
00130          if (err == REG_NOMATCH)
00131            {
00132              puts ("\nregexec failed");
00133              return 1;
00134            }
00135 
00136          if (testno == 0)
00137            {
00138              if (pmatch[0].rm_eo != pmatch[0].rm_so + 13
00139                 || pmatch[0].rm_eo > len
00140                 || pmatch[0].rm_so < len - 100
00141                 || strncmp (string + pmatch[0].rm_so,
00142                            " ChangeLog.13 for earlier changes",
00143                            sizeof " ChangeLog.13 for earlier changes" - 1)
00144                    != 0)
00145               {
00146                 puts ("\nregexec without REG_NOSUB did not find the correct match");
00147                 return 1;
00148               }
00149 
00150              if (i > 0)
00151               for (int j = 0, l = 1; j < 7; ++j)
00152                 for (int k = 0; k < (i == 1 ? 1 : 10); ++k, ++l)
00153                   if (pmatch[l].rm_so != pmatch[0].rm_so + j
00154                      || pmatch[l].rm_eo != pmatch[l].rm_so + 1)
00155                     {
00156                      printf ("\npmatch[%d] incorrect\n", l);
00157                      return 1;
00158                     }
00159            }
00160        }
00161       else
00162        {
00163          struct re_registers regs;
00164 
00165          memset (&regs, 0, sizeof (regs));
00166          int match = re_search (&rpbuf, string, len, 0, len,
00167                              &regs);
00168          if (match < 0)
00169            {
00170              puts ("\nre_search failed");
00171              return 1;
00172            }
00173 
00174          if (match + 13 > len
00175              || match < len - 100
00176              || strncmp (string + match,
00177                        " ChangeLog.13 for earlier changes",
00178                        sizeof " ChangeLog.13 for earlier changes" - 1)
00179                 != 0)
00180            {
00181              puts ("\nre_search did not find the correct match");
00182              return 1;
00183            }
00184 
00185          if (testno == 2)
00186            {
00187              if (regs.num_regs != 2 + (i == 0 ? 0 : i == 1 ? 7 : 70))
00188               {
00189                 printf ("\nincorrect num_regs %d\n", regs.num_regs);
00190                 return 1;
00191               }
00192 
00193              if (regs.start[0] != match || regs.end[0] != match + 13)
00194               {
00195                 printf ("\nincorrect regs.{start,end}[0] = { %d, %d}\n",
00196                        regs.start[0], regs.end[0]);
00197                 return 1;
00198               }
00199 
00200              if (regs.start[regs.num_regs - 1] != -1
00201                 || regs.end[regs.num_regs - 1] != -1)
00202               {
00203                 puts ("\nincorrect regs.{start,end}[num_regs - 1]");
00204                 return 1;
00205               }
00206 
00207              if (i > 0)
00208               for (int j = 0, l = 1; j < 7; ++j)
00209                 for (int k = 0; k < (i == 1 ? 1 : 10); ++k, ++l)
00210                   if (regs.start[l] != match + j
00211                      || regs.end[l] != regs.start[l] + 1)
00212                     {
00213                      printf ("\nregs.{start,end}[%d] incorrect\n", l);
00214                      return 1;
00215                     }
00216            }
00217        }
00218 
00219 #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
00220       if (use_clock)
00221        use_clock = clock_gettime (cl, &stop) == 0;
00222       if (use_clock)
00223        {
00224          stop.tv_sec -= start.tv_sec;
00225          if (stop.tv_nsec < start.tv_nsec)
00226            {
00227              stop.tv_sec--;
00228              stop.tv_nsec += 1000000000 - start.tv_nsec;
00229            }
00230          else
00231            stop.tv_nsec -= start.tv_nsec;
00232          printf (": %ld.%09lds\n", (long) stop.tv_sec, (long) stop.tv_nsec);
00233        }
00234       else
00235 #endif
00236        putchar ('\n');
00237 
00238       if (testno < 2)
00239        regfree (&rbuf);
00240       else
00241        regfree (&rpbuf);
00242     }
00243 
00244   return 0;
00245 }
00246 
00247 #define TIMEOUT 20
00248 #define TEST_FUNCTION do_test ()
00249 #include "../test-skeleton.c"