tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

linux.c (4446B)


      1 /* contrib/arm-neon/linux.c
      2 *
      3 * Copyright (c) 2014, 2017 Glenn Randers-Pehrson
      4 * Written by John Bowler, 2014, 2017.
      5 *
      6 * This code is released under the libpng license.
      7 * For conditions of distribution and use, see the disclaimer
      8 * and license in png.h
      9 *
     10 * SEE contrib/arm-neon/README before reporting bugs
     11 *
     12 * STATUS: SUPPORTED
     13 * BUG REPORTS: png-mng-implement@sourceforge.net
     14 *
     15 * png_have_neon implemented for Linux by reading the widely available
     16 * pseudo-file /proc/cpuinfo.
     17 *
     18 * This code is strict ANSI-C and is probably moderately portable; it does
     19 * however use <stdio.h> and it assumes that /proc/cpuinfo is never localized.
     20 */
     21 
     22 #include <stdio.h>
     23 
     24 static int
     25 png_have_neon(png_structp png_ptr)
     26 {
     27   FILE *f = fopen("/proc/cpuinfo", "rb");
     28 
     29   if (f != NULL)
     30   {
     31      /* This is a simple state machine which reads the input byte-by-byte until
     32       * it gets a match on the 'neon' feature or reaches the end of the stream.
     33       */
     34      static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 };
     35      static const char ch_neon[] = { 78, 69, 79, 78 };
     36 
     37      enum
     38      {
     39         StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine
     40      }  state;
     41      int counter;
     42 
     43      for (state=StartLine, counter=0;;)
     44      {
     45         int ch = fgetc(f);
     46 
     47         if (ch == EOF)
     48         {
     49            /* EOF means error or end-of-file, return false; neon at EOF is
     50             * assumed to be a mistake.
     51             */
     52            fclose(f);
     53            return 0;
     54         }
     55 
     56         switch (state)
     57         {
     58            case StartLine:
     59               /* Match spaces at the start of line */
     60               if (ch <= 32) /* skip control characters and space */
     61                  break;
     62 
     63               counter=0;
     64               state = Feature;
     65               /* FALLTHROUGH */
     66 
     67            case Feature:
     68               /* Match 'FEATURE', ASCII case insensitive. */
     69               if ((ch & ~0x20) == ch_feature[counter])
     70               {
     71                  if (++counter == (sizeof ch_feature))
     72                     state = Colon;
     73                  break;
     74               }
     75 
     76               /* did not match 'feature' */
     77               state = SkipLine;
     78               /* FALLTHROUGH */
     79 
     80            case SkipLine:
     81            skipLine:
     82               /* Skip everything until we see linefeed or carriage return */
     83               if (ch != 10 && ch != 13)
     84                  break;
     85 
     86               state = StartLine;
     87               break;
     88 
     89            case Colon:
     90               /* Match any number of space or tab followed by ':' */
     91               if (ch == 32 || ch == 9)
     92                  break;
     93 
     94               if (ch == 58) /* i.e. ':' */
     95               {
     96                  state = StartTag;
     97                  break;
     98               }
     99 
    100               /* Either a bad line format or a 'feature' prefix followed by
    101                * other characters.
    102                */
    103               state = SkipLine;
    104               goto skipLine;
    105 
    106            case StartTag:
    107               /* Skip space characters before a tag */
    108               if (ch == 32 || ch == 9)
    109                  break;
    110 
    111               state = Neon;
    112               counter = 0;
    113               /* FALLTHROUGH */
    114 
    115            case Neon:
    116               /* Look for 'neon' tag */
    117               if ((ch & ~0x20) == ch_neon[counter])
    118               {
    119                  if (++counter == (sizeof ch_neon))
    120                     state = HaveNeon;
    121                  break;
    122               }
    123 
    124               state = SkipTag;
    125               /* FALLTHROUGH */
    126 
    127            case SkipTag:
    128               /* Skip non-space characters */
    129               if (ch == 10 || ch == 13)
    130                  state = StartLine;
    131 
    132               else if (ch == 32 || ch == 9)
    133                  state = StartTag;
    134               break;
    135 
    136            case HaveNeon:
    137               /* Have seen a 'neon' prefix, but there must be a space or new
    138                * line character to terminate it.
    139                */
    140               if (ch == 10 || ch == 13 || ch == 32 || ch == 9)
    141               {
    142                  fclose(f);
    143                  return 1;
    144               }
    145 
    146               state = SkipTag;
    147               break;
    148 
    149            default:
    150               png_error(png_ptr, "png_have_neon: internal error (bug)");
    151         }
    152      }
    153   }
    154 
    155 #ifdef PNG_WARNINGS_SUPPORTED
    156   else
    157      png_warning(png_ptr, "/proc/cpuinfo open failed");
    158 #endif
    159 
    160   return 0;
    161 }