Update a configuration file: Difference between revisions

Content added Content deleted
(→‎{{header|C}}: Time a Real Programmer solution to shame the script jockeys. :) With innovative, Lisp-inspired code formatting.)
Line 146: Line 146:


FileCopy, %A_scriptdir%\rosettaconfig.tmp, %A_scriptdir%\rosettaconfig.txt, 1</lang>
FileCopy, %A_scriptdir%\rosettaconfig.tmp, %A_scriptdir%\rosettaconfig.txt, 1</lang>

=={{header|C}}==

C with POSIX <code>strcasecmp</code> function for case-insensitive comparing. Substitute your toolchain's version.

<lang C>#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define strcomp(X, Y) strcasecmp(X, Y)

struct option
{ char *name, *value;
int flag; };

/* TODO: dynamically obtain these */
struct option updlist[] =
{ { "NEEDSPEELING", NULL },
{ "SEEDSREMOVED", "" },
{ "NUMBEROFBANANAS", "1024" },
{ "NUMBEROFSTRAWBERRIES", "62000" },
{ NULL, NULL } };

int output_opt(FILE *to, struct option *opt)
{ if (opt->value == NULL)
return fprintf(to, "; %s\n", opt->name);
else if (opt->value[0] == 0)
return fprintf(to, "%s\n", opt->name);
else
return fprintf(to, "%s %s\n", opt->name, opt->value); }

int update(FILE *from, FILE *to, struct option *updlist)
{ char line_buf[256], opt_name[128];
int i;
for (;;)
{ size_t len, space_span, span_to_hash;
if (fgets(line_buf, sizeof line_buf, from) == NULL)
break;
len = strlen(line_buf);
space_span = strspn(line_buf, "\t ");
span_to_hash = strcspn(line_buf, "#");
if (space_span == span_to_hash)
goto line_out;
if (space_span == len)
goto line_out;
if ((sscanf(line_buf, "; %127s", opt_name) == 1) ||
(sscanf(line_buf, "%127s", opt_name) == 1))
{ int flag = 0;
for (i = 0; updlist[i].name; i++)
{ if (strcomp(updlist[i].name, opt_name) == 0)
{ if (output_opt(to, &updlist[i]) < 0)
return -1;
updlist[i].flag = 1;
flag = 1; } }
if (flag == 0)
goto line_out; }
else
line_out:
if (fprintf(to, "%s", line_buf) < 0)
return -1;
continue; }
{ for (i = 0; updlist[i].name; i++)
{ if (!updlist[i].flag)
if (output_opt(to, &updlist[i]) < 0)
return -1; }}
return feof(from) ? 0 : -1; }

int main(void)
{ if (update(stdin, stdout, updlist) < 0)
{ fprintf(stderr, "failed\n");
return (EXIT_FAILURE); }
return 0; }</lang>

Run:

<pre>$ ./a.out < configfile
# This is a configuration file in standard configuration file format
#
# Lines begininning with a hash or a semicolon are ignored by the application
# program. Blank lines are also ignored by the application program.

# The first word on each non comment line is the configuration option.
# Remaining words or numbers on the line are configuration parameter
# data fields.

# Note that configuration option names are not case sensitive. However,
# configuration parameter data is case sensitive and the lettercase must
# be preserved.

# This is a favourite fruit
FAVOURITEFRUIT banana

# This is a boolean that should be set
; NEEDSPEELING

# This boolean is commented out
SEEDSREMOVED

# How many bananas we have
NUMBEROFBANANAS 1024
NUMBEROFSTRAWBERRIES 62000</pre>


=={{header|Perl}}==
=={{header|Perl}}==