/ util / kconfig / toada.c
toada.c
  1  /* SPDX-License-Identifier: GPL-2.0-or-later */
  2  
  3  #include <ctype.h>
  4  #include <stdio.h>
  5  #include <string.h>
  6  #include <stdbool.h>
  7  #include <stdlib.h>
  8  
  9  static void print_bool(const char *const name, const bool val)
 10  {
 11  	printf("   %-46s : constant boolean := %s;\n",
 12  	       name, val ? "true" : "false");
 13  }
 14  
 15  static void print_hex(const char *const name, const char *val)
 16  {
 17  	unsigned int hexlen;
 18  
 19  	printf("   %-46s : constant         := 16#", name);
 20  	for (hexlen = strlen(val); hexlen > 0;) {
 21  		const unsigned int len = hexlen % 4 ? : 4;
 22  		char quad[] = "0000";
 23  		unsigned int i;
 24  
 25  		for (i = 0; i < len; ++i)
 26  			quad[4 - len + i] = val[i];
 27  		printf("%s", quad);
 28  
 29  		val += len;
 30  		hexlen -= len;
 31  		if (hexlen > 0)
 32  			printf("_");
 33  	}
 34  	printf ("#;\n");
 35  }
 36  
 37  static void print_dec(const char *const name, const char *const val)
 38  {
 39  	printf("   %-46s : constant         := %s;\n", name, val);
 40  }
 41  
 42  static void print_string(const char *const name, const char *const val)
 43  {
 44  	printf("   %-46s : constant string  := \"%s\";\n", name, val);
 45  }
 46  
 47  int main(int argc, char *argv[])
 48  {
 49  	char unset_fmt[256], string_fmt[256], set_fmt[256], line[256];
 50  	char *prefix = "CONFIG", *package = "KConfig";
 51  
 52  	if (argc > 3) {
 53  		fprintf(stderr,
 54  			"Usage: %s [<package name> [<config prefix>]]\n\n",
 55  			argv[0]);
 56  		return 1;
 57  	}
 58  	if (argc > 2)
 59  		prefix = argv[2];
 60  	if (argc > 1)
 61  		package = argv[1];
 62  
 63  	snprintf(set_fmt, sizeof(set_fmt), "%s_%%255[^=]=%%255s", prefix);
 64  	snprintf(string_fmt, sizeof(string_fmt),
 65  		 "%s_%%255[^=]=\"%%255[^\"]\"", prefix);
 66  	snprintf(unset_fmt, sizeof(unset_fmt),
 67  		 "# %s_%%255s is not set", prefix);
 68  
 69  	printf("package %s is\n\n", package);
 70  
 71  	while (fgets(line, sizeof(line), stdin)) {
 72  		char name[256], val[256];
 73  
 74  		if (line[strlen(line) - 1] != '\n') {
 75  			fprintf(stderr,
 76  				"Line longer than %zu chars, skipping...\n",
 77  				sizeof(line) - 1);
 78  			while (fgets(line, sizeof(line), stdin)) {
 79  				if (line[strlen(line) - 1] == '\n')
 80  					break;
 81  			}
 82  			continue;
 83  		}
 84  
 85  		if (sscanf(line, unset_fmt, name) == 1) {
 86  			print_bool(name, false);
 87  			continue;
 88  		}
 89  
 90  		if (sscanf(line, string_fmt, name, val) == 2) {
 91  			print_string(name, val);
 92  			continue;
 93  		}
 94  
 95  		switch (sscanf(line, set_fmt, name, val)) {
 96  		case 1:
 97  			/* ignore for now, our Kconfig is full of these atm */
 98  			/* fprintf(stderr, "unset non-bool: %s=\n", name); */
 99  			continue;
100  		case 2:
101  			if (strcmp(val, "\"\"") == 0) {
102  				print_string(name, "");
103  			} else if (strcmp(val, "y") == 0) {
104  				print_bool(name, true);
105  			} else if (strncmp(val, "0x", 2) == 0) {
106  				print_hex(name, val + 2);
107  			} else if (isdigit(val[0]) || (val[0] == '-' && isdigit(val[1]))) {
108  				print_dec(name, val);
109  			} else {
110  				fprintf(stderr,
111  					"toada: Error: Couldn't parse value '%s' for '%s'\n",
112  					val, name);
113  				exit(1);
114  			}
115  			continue;
116  		default:
117  			break;
118  		}
119  
120  		unsigned int i = 0;
121  		while (isspace(line[i]))
122  			++i;
123  		if (line[i] == '#') {
124  			printf("   --%s", line + i + 1);
125  			continue;
126  		} else if (i == strlen(line)) {
127  			continue;
128  		}
129  
130  		fprintf(stderr, "spurious line:\n%s", line);
131  	}
132  
133  	printf("\nend %s;\n", package);
134  	return 0;
135  }