1a46c0ec8Sopenharmony_ci#pragma once 2a46c0ec8Sopenharmony_ci 3a46c0ec8Sopenharmony_ci/* Copyright © 2005-2014 Rich Felker, et al. 4a46c0ec8Sopenharmony_ci * 5a46c0ec8Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 6a46c0ec8Sopenharmony_ci * a copy of this software and associated documentation files (the 7a46c0ec8Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 8a46c0ec8Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 9a46c0ec8Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 10a46c0ec8Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 11a46c0ec8Sopenharmony_ci * the following conditions: 12a46c0ec8Sopenharmony_ci * 13a46c0ec8Sopenharmony_ci * The above copyright notice and this permission notice shall be 14a46c0ec8Sopenharmony_ci * included in all copies or substantial portions of the Software. 15a46c0ec8Sopenharmony_ci * 16a46c0ec8Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17a46c0ec8Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18a46c0ec8Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19a46c0ec8Sopenharmony_ci * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20a46c0ec8Sopenharmony_ci * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21a46c0ec8Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22a46c0ec8Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23a46c0ec8Sopenharmony_ci */ 24a46c0ec8Sopenharmony_ci 25a46c0ec8Sopenharmony_ci#include "config.h" 26a46c0ec8Sopenharmony_ci 27a46c0ec8Sopenharmony_ci#include <ctype.h> 28a46c0ec8Sopenharmony_ci#include <string.h> 29a46c0ec8Sopenharmony_ci#include <dirent.h> 30a46c0ec8Sopenharmony_ci 31a46c0ec8Sopenharmony_ci#if !defined(HAVE_VERSIONSORT) || defined(TEST_VERSIONSORT) 32a46c0ec8Sopenharmony_cistatic inline int 33a46c0ec8Sopenharmony_cilibinput_strverscmp(const char *l0, const char *r0) 34a46c0ec8Sopenharmony_ci{ 35a46c0ec8Sopenharmony_ci const unsigned char *l = (const void *)l0; 36a46c0ec8Sopenharmony_ci const unsigned char *r = (const void *)r0; 37a46c0ec8Sopenharmony_ci size_t i, dp, j; 38a46c0ec8Sopenharmony_ci int z = 1; 39a46c0ec8Sopenharmony_ci 40a46c0ec8Sopenharmony_ci /* Find maximal matching prefix and track its maximal digit 41a46c0ec8Sopenharmony_ci * suffix and whether those digits are all zeros. */ 42a46c0ec8Sopenharmony_ci for (dp=i=0; l[i]==r[i]; i++) { 43a46c0ec8Sopenharmony_ci int c = l[i]; 44a46c0ec8Sopenharmony_ci if (!c) return 0; 45a46c0ec8Sopenharmony_ci if (!isdigit(c)) dp=i+1, z=1; 46a46c0ec8Sopenharmony_ci else if (c!='0') z=0; 47a46c0ec8Sopenharmony_ci } 48a46c0ec8Sopenharmony_ci 49a46c0ec8Sopenharmony_ci if (l[dp]!='0' && r[dp]!='0') { 50a46c0ec8Sopenharmony_ci /* If we're not looking at a digit sequence that began 51a46c0ec8Sopenharmony_ci * with a zero, longest digit string is greater. */ 52a46c0ec8Sopenharmony_ci for (j=i; isdigit(l[j]); j++) 53a46c0ec8Sopenharmony_ci if (!isdigit(r[j])) return 1; 54a46c0ec8Sopenharmony_ci if (isdigit(r[j])) return -1; 55a46c0ec8Sopenharmony_ci } else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) { 56a46c0ec8Sopenharmony_ci /* Otherwise, if common prefix of digit sequence is 57a46c0ec8Sopenharmony_ci * all zeros, digits order less than non-digits. */ 58a46c0ec8Sopenharmony_ci return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0'); 59a46c0ec8Sopenharmony_ci } 60a46c0ec8Sopenharmony_ci 61a46c0ec8Sopenharmony_ci return l[i] - r[i]; 62a46c0ec8Sopenharmony_ci} 63a46c0ec8Sopenharmony_ci#endif 64a46c0ec8Sopenharmony_ci 65a46c0ec8Sopenharmony_ci/* Defined with libinput_ names for testing from platforms with native functions. */ 66a46c0ec8Sopenharmony_ci 67a46c0ec8Sopenharmony_ci#ifndef HAVE_VERSIONSORT 68a46c0ec8Sopenharmony_cistatic inline int 69a46c0ec8Sopenharmony_cistrverscmp(const char *l0, const char *r0) 70a46c0ec8Sopenharmony_ci{ 71a46c0ec8Sopenharmony_ci return libinput_strverscmp(l0, r0); 72a46c0ec8Sopenharmony_ci} 73a46c0ec8Sopenharmony_ci 74a46c0ec8Sopenharmony_cistatic inline int 75a46c0ec8Sopenharmony_civersionsort(const struct dirent **a, const struct dirent **b) 76a46c0ec8Sopenharmony_ci{ 77a46c0ec8Sopenharmony_ci return libinput_strverscmp((*a)->d_name, (*b)->d_name); 78a46c0ec8Sopenharmony_ci} 79a46c0ec8Sopenharmony_ci#endif 80