mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00:00 
			
		
		
		
	 e02da2ed41
			
		
	
	
		e02da2ed41
		
	
	
	
	
		
			
			This is a LibC function that POSIX defines to help userspace programs to get suboptions. An example of a suboption is the token "pixclk" from a Shell command running "edid-decode --gtf w=1024,h=768,pixclk=48". The function should be run in a while loop to acquire all suboptions until the last one.
		
			
				
	
	
		
			51 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			51 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #include <AK/ScopeGuard.h>
 | |
| #include <AK/StringView.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| // https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsubopt.html
 | |
| int getsubopt(char** option_array, char* const* tokens, char** option_value)
 | |
| {
 | |
|     if (**option_array == '\0')
 | |
|         return -1;
 | |
| 
 | |
|     auto option_string = StringView(*option_array);
 | |
| 
 | |
|     auto possible_comma_location = option_string.find(',');
 | |
|     char* option_end = const_cast<char*>(option_string.characters_without_null_termination()) + possible_comma_location.value_or(option_string.length());
 | |
| 
 | |
|     auto possible_equals_char_location = option_string.find('=');
 | |
|     char* value_start = option_end;
 | |
|     if (possible_equals_char_location.has_value()) {
 | |
|         value_start = const_cast<char*>(option_string.characters_without_null_termination()) + possible_equals_char_location.value();
 | |
|     }
 | |
| 
 | |
|     ScopeGuard ensure_end_array_contains_null_char([&]() {
 | |
|         if (*option_end != '\0')
 | |
|             *option_end++ = '\0';
 | |
|         *option_array = option_end;
 | |
|     });
 | |
| 
 | |
|     for (int count = 0; tokens[count] != NULL; ++count) {
 | |
|         auto token_stringview = StringView(tokens[count]);
 | |
|         if (!option_string.starts_with(token_stringview))
 | |
|             continue;
 | |
|         if (tokens[count][value_start - *option_array] != '\0')
 | |
|             continue;
 | |
| 
 | |
|         *option_value = value_start != option_end ? value_start + 1 : nullptr;
 | |
|         return count;
 | |
|     }
 | |
| 
 | |
|     // Note: The current sub-option does not match any option, so prepare to tell this
 | |
|     // to the application.
 | |
|     *option_value = *option_array;
 | |
|     return -1;
 | |
| }
 |