<commit_before>/**
* @file ROT13.c
* @brief Implementation of Rotate by 13 places (ROT-13).
* @author <NAME> <<EMAIL>>
* @version 1.0
* @copyright 2015
*
* @section LICENSE
* Copyright (C) 2015 <NAME>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <argp.h>

/* Print --version. */
const char *argp_program_version =
"ROT13 1.0.0\n\
Copyright (C) 2015 Star Poon\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
This is free software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\
\n\
Written by Star Poon.";

/* Print --help. */
const char *argp_program_bug_address =
  "Star Poon <<EMAIL>>";

/* A descriptive string about this program. */
static char doc[] =
  "ROT13 -- Rotate by 13 places encryption";

static char args_doc[] = "[FILE...]";

static struct argp_option options[] = {
        {"shift",   's',    "AMOUNT",      0,  "Shift by this AMOUNT. (default 13)" },
        {"reverse", 'r',    0,      0,  "Reverse shift (right shift)." },
        { 0 }
};

/* Used by main to communicate with parse_opt. */
struct arguments
{
    long int shift;
    int reverse;
    char **strings;               /* [FILE…] */
};

/**
 * @brief Error handling for strtol().
 */
int parseLong(const char *str, long *ret)
{
    errno = 0;
    char *temp;
    long val = strtol(str, &temp, 0);

    if (temp == str || *temp != '\0' ||
        ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE))
        return 1;   //Failed to convert to int
    *ret = val;
    return 0;
}

/**
 * @brief Parse a single option.
 */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
    /* Get the input argument from argp_parse, which we
       know is a pointer to our arguments structure. */
    long ret, arg_int;
    struct arguments *arguments = state->input;
    switch (key)
    {
        case 's':
            ret = parseLong(arg, &arg_int);
            if(ret) {
                // Print error and exit()
                argp_error(state, "%s", strerror(EINVAL));
            }
            arguments->shift = arg_int;
            break;
        case 'r':
            arguments->reverse = 1;
            break;
        case ARGP_KEY_ARG:
            arguments->strings = &state->argv[state->next-1];
            state->next = state->argc;
            break;
        default:
            return ARGP_ERR_UNKNOWN;
    }
    return 0;
}

static struct argp argp = { options, parse_opt, args_doc, doc };

char c;
int main (int argc, char **argv)
{
    struct arguments arguments = {
            .shift = 13
    };
    error_t ret = argp_parse(&argp, argc, argv, 0, 0, &arguments);
    if(ret) {
        fprintf(stderr, "%s: Unknown error during parsing argument: %s\n", argv[0], strerror(ret));
        return EXIT_FAILURE;
    }

    /* Optional File Name */
    if (arguments.strings) {
        int j;
        printf ("STRINGS = ");
        for (j = 0; arguments.strings[j]; j++)
            printf(j == 0 ? "%s" : ", %s", arguments.strings[j]);
        printf("\n");
    }

    printf("Shift=%ld, Reverse=%d\n", arguments.shift, arguments.reverse);
    do {
        // Read a character from stdin
        c = fgetc(stdin);
        // End of file? Nothing left to read...
        if (feof(stdin)) {
            // Exit loop
            break;
        }

        // Is the character lower case?
//        if ((c >= 'a') && (c <= 'z')) {
//            // Yes, let's make it upper case
//            c = arguments.reverse? c+arguments.shift: c-arguments.shift;
//        }

        // Encrypt
        if (c >='A' && c<='Z') {
            // Shift
            c = arguments.reverse? c+arguments.shift: c-arguments.shift;

            // Range check
            if (c > 'Z') {
                c -= 26;
            }
            else if (c < 'A') {
                c += 26;
            }
        }

        if (c >='a' && c<='z') {
            // Shift
            c = arguments.reverse? c+arguments.shift: c-arguments.shift;

            // Range check
            if (c > 'z') {
                c -= 26;
            }
            else if (c < 'a') {
                c += 26;
            }
        }
        // Print the character to stdout (default)
        printf("%c", c);
    } while (1);
    // Exit cleanly
    return EXIT_SUCCESS;

}
<commit_msg>Implementing the file input.<commit_after>/**
* @file ROT13.c
* @brief Implementation of Rotate by 13 places (ROT-13).
* @author <NAME> <<EMAIL>>
* @version 1.0
* @copyright 2015
*
* @section LICENSE
* Copyright (C) 2015 <NAME>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>

#include <errno.h>
#include <string.h>
#include <argp.h>

/* Print --version. */
const char *argp_program_version =
"ROT13 1.0.0\n\
Copyright (C) 2015 <NAME>\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
This is free software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\
\n\
Written by <NAME>.";

/* Print --help. */
const char *argp_program_bug_address =
  "Star Poon <<EMAIL>>";

/* A descriptive string about this program. */
static char doc[] =
  "ROT13 -- Rotate by 13 places encryption";

static char args_doc[] = "[FILE...]";

static struct argp_option options[] = {
        {"shift",   's',    "AMOUNT",      0,  "Shift by this AMOUNT. (default 13)" },
        {"reverse", 'r',    0,      0,  "Reverse shift (right shift)." },
        { 0 }
};

/* Used by main to communicate with parse_opt. */
struct arguments
{
    long int shift;
    int reverse;
    char **strings;               /* [FILE…] */
};

/**
 * @brief Error handling for strtol().
 */
int parseLong(const char *str, long *ret)
{
    errno = 0;
    char *temp;
    long val = strtol(str, &temp, 0);

    if (temp == str || *temp != '\0' ||
        ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE))
        return 1;   //Failed to convert to int
    *ret = val;
    return 0;
}

/**
 * @brief Parse a single option.
 */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
    /* Get the input argument from argp_parse, which we
       know is a pointer to our arguments structure. */
    long ret, arg_int;
    struct arguments *arguments = state->input;
    switch (key)
    {
        case 's':
            ret = parseLong(arg, &arg_int);
            if(ret) {
                // Print error and exit()
                argp_error(state, "%s", strerror(EINVAL));
            }
            arguments->shift = arg_int;
            break;
        case 'r':
            arguments->reverse = 1;
            break;
        case ARGP_KEY_ARG:
            arguments->strings = &state->argv[state->next-1];
            state->next = state->argc;
            break;
        default:
            return ARGP_ERR_UNKNOWN;
    }
    return 0;
}

static struct argp argp = { options, parse_opt, args_doc, doc };
static struct arguments arguments = {
        .shift = 13
};

int convert_file(FILE *inFile, FILE *outFile)
{
    do {
        // Read a character from stdin
        int c = fgetc(inFile);
        // End of file? Nothing left to read...
        if (feof(inFile)) {
            // Exit loop
            break;
        }

        // Encrypt
        if (c >='A' && c<='Z') {
            // Shift
            c = arguments.reverse? c+arguments.shift: c-arguments.shift;

            // Range check
            if (c > 'Z') {
                c -= 26;
            }
            else if (c < 'A') {
                c += 26;
            }
        }

        if (c >='a' && c<='z') {
            // Shift
            c = arguments.reverse? c+arguments.shift: c-arguments.shift;

            // Range check
            if (c > 'z') {
                c -= 26;
            }
            else if (c < 'a') {
                c += 26;
            }
        }
        // Print the character to stdout (default)
        fprintf(outFile, "%c", c);
    } while (1);
    return 0;
}

char c;
int main (int argc, char **argv)
{
    error_t ret = argp_parse(&argp, argc, argv, 0, 0, &arguments);
    if(ret) {
        fprintf(stderr, "%s: Unknown error during parsing argument: %s\n", argv[0], strerror(ret));
        return EXIT_FAILURE;
    }

    if (arguments.strings) {
        // Provided File Name -> Convert files
        for (int j = 0; arguments.strings[j]; j++) {

            FILE *inFile, *outFile;
            inFile = fopen (arguments.strings[j],"r");
            if(!inFile) {
                fprintf(stderr, "%s: Failed to open file '%s': %s\n", argv[0], arguments.strings[j], strerror(errno));
                return EXIT_FAILURE;
            }
            char temp_file_name[] = "fileXXXXXX";

            int temp_fd = mkstemp(temp_file_name);
            outFile = fdopen(temp_fd, "w");
            printf("TempFile = %s\n", temp_file_name);
            if(!outFile) {
                fprintf(stderr, "%s: Failed to create temp file: %s\n", argv[0], strerror(errno));
                return EXIT_FAILURE;
            }
            convert_file(inFile, outFile);

            fclose(inFile);
            fclose(outFile);

            // "filename"+".out" as the output
            if (strlen(arguments.strings[j])+4>=FILENAME_MAX) {
                // if "filename"+".out" is too long, just clean up and terminate the program.
                remove(temp_file_name);
                return EXIT_FAILURE;
            }

            // According to GCC standard, we shouldn't use FILENAME_MAX as the size of an array in which to store a
            // file name.  Use dynamic allocation instead.
            // I doubt that but we just follow it here.
            char *final_output = malloc(strlen(arguments.strings[j])+4);
            snprintf(final_output, FILENAME_MAX, "%s.out", arguments.strings[j]);
            remove(final_output);
            rename(temp_file_name, final_output);
            free(final_output);
        }
    } else {
        // No file name provided -> Convert stdin
        convert_file(stdin, stdout);
    }

    printf("Shift=%ld, Reverse=%d\n", arguments.shift, arguments.reverse);

    // Exit cleanly
    return EXIT_SUCCESS;

}

{'fraction_non_alphanumeric': 0.13296808418123315, 'fraction_numerical': 0.011131402730672233, 'mean_word_length': 1.917300862506342, 'pattern_counts': {'":': 0, '<': 40, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2425056', 'n_tokens_mistral': 3637, 'n_tokens_neox': 3455, 'n_words': 1164}