Thread: can someone check this out and let me know ?

  1. #1
    Registered User
    Join Date
    Dec 2001
    Posts
    5

    Cool can someone check this out and let me know ?

    /************************************************** **************************
    *
    * FILE: mkmotd.c
    *
    * PURPOSE: Make a message-of-the-day database
    *
    * DESCRIPTION: A message-of-the-day database has a specific format that
    * must be followed so that all programs that use the data
    * can use it correctly.
    *
    * Most of the records in the database are simply null-
    * terminated text strings that contain messages, one per
    * record. The database's first record is special, and contains
    * the following information:
    *
    * mode (4 bytes, unsigned) - this field describes how the
    * text records in the rest of the database are used:
    *
    * mode = 1: only the first text record is used, and it is
    * used over and over again. PalmJournal can use
    * this mode to insert a standard text template
    * into every day's new journal entry.
    * mode = 2: each record is used in turn, starting with the
    * first text record. This is useful for a message
    * of the day, where the particular day doesn't
    * matter. The most recently-used record's index
    * can be stored in the last_used field (below)
    * to keep things in order. When the last record
    * has been used, the program starts over again
    * at the first record.
    * mode = 3: only the first 7 records are used, based on the
    * day of the week. The first record is for Sunday,
    * the second for Monday, etc. PalmJournal can use
    * this mode to provide a different text template
    * for each weekday's journal entry.
    * mode = 4: there must be at least 366 records for this mode.
    * Each record corresponds to a day of the year.
    * **NOTE: Feruary 29 is treated specially... it's
    * always the 366th day. This way, each day's number
    * within the year is constant, regardless of leap
    * year.
    *
    * last_used (2 bytes, unsigned) - this field is really only
    * useful for mode 2, since the other modes always determine
    * which record number to use by some other method. Only mode
    * 2 requires the program to remember which record was used
    * last.
    *
    * This program takes a single command-line argument: the mode
    * number for the resulting database (see above).
    *
    * This program reads the input file "motddb.txt" (in the
    * current directory) as the source of the text records for the
    * database. Each record in the file must be on a single line,
    * and empty lines are not allowed. Records may include linefeeds
    * as "\n" in the text.
    *
    * This program creates the file "motddb.pdb" in the current
    * directory. This program also assumes that it is being run
    * on an INTEL-like processor, and so will byte-swap short and
    * long integers. Just change the SSwap and LSwap routines if
    * you compile this on some other architecture.
    *
    * REVISION HISTORY:
    * v 1.0 Original release
    * v 1.1 Increased maximum line length to 4096, fixed international
    * character compatibility, added command-line parameters
    ************************************************** **************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #define TRUE 1
    #define FALSE 0

    /* this is a PALM OS standard -- do not change */
    #define DB_NAME_SIZE 32

    /* this is an arbitrary number, make it whatever you want */
    #define MAX_RECORDS 400

    /* again, an arbitrary number, for convenient programming */
    #define MAX_LINE_LENGTH 4096

    /* the linefeed character */
    #define LF 0x0a

    /* the file names */
    char *outfile_name = "motddb.pdb";
    char *infile_name = "motddb.txt";

    /* there shouldn't be any need to change these initial values */
    char db_name[DB_NAME_SIZE];
    unsigned short db_attributes = 0;
    unsigned short db_version = 0;
    unsigned long db_creation_date = 0x32cb1cc2;
    unsigned long db_modification_date = 0x32cb1cc2;
    unsigned long db_last_backup_date = 0x32cb1cc2;
    unsigned long db_modification_number = 1;
    unsigned long db_app_info_id = 0;
    unsigned long db_sort_info_id = 0;
    unsigned char db_type[4] = {'D', 'a', 't', 'a'};
    unsigned char db_creator[4] = {'C', 'k', 's', '4'};
    unsigned long db_unique_id_seed = 0;
    unsigned long db_next_record_list_id = 0;
    unsigned short db_num_records = 0;

    unsigned char rec_attributes = 0;

    /* this is a pointer to the buffer that holds the records when they are
    read in */
    char *record[MAX_RECORDS];

    /* local function prototypes */
    long get_records(void);
    unsigned long LSwap(unsigned long l);
    unsigned short SSwap(unsigned short s);
    char *transform(char *s);

    /************************************************** *************************
    * main()
    ************************************************** *************************/
    main(int argc, char * argv[]) {
    FILE *outfile;
    unsigned long mode = 2;
    unsigned short last_used = 0;
    unsigned short i;
    long pad = 0;
    unsigned long offset = 80;
    unsigned char temp_char;
    unsigned short temp_short;
    unsigned long temp_long;

    for (i = 1; i < argc; i++) {
    if (argv[i][0] == '-') {
    switch (argv[i][1]) {
    case 'm':
    if (argc > (i + 1))
    mode = atol(argv[i + 1]);
    break;
    case 'i':
    if (argc > (i + 1))
    infile_name = argv[i + 1];
    break;
    case 'o':
    if (argc > (i + 1))
    outfile_name = argv[i + 1];
    break;
    default:
    printf("usage: mkmotd [-m mode] [-i input file] [-o output file]\n");
    printf(" default mode is 2\n");
    printf(" default input file is motddb.txt\n");
    printf(" default output file is motddb.pdb\n");
    return(1);
    break;
    }
    }
    }

    printf("mkmotd: mode = %ld\ninput file = %s\noutput file = %s\n", mode, infile_name, outfile_name);

    outfile = fopen(outfile_name, "wb");
    if (outfile) {

    memset(db_name, 0, DB_NAME_SIZE);
    strcpy(db_name, "MOTDDB");
    fwrite(db_name, DB_NAME_SIZE, 1, outfile);

    temp_short = SSwap(db_attributes);
    fwrite(&temp_short, sizeof(temp_short), 1, outfile);

    temp_short = SSwap(db_version);
    fwrite(&temp_short, sizeof(temp_short), 1, outfile);

    temp_long = LSwap(db_creation_date);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    temp_long = LSwap(db_modification_date);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    temp_long = LSwap(db_last_backup_date);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    temp_long = LSwap(db_modification_number);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    temp_long = LSwap(db_app_info_id);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    temp_long = LSwap(db_sort_info_id);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    fwrite(&db_type, 4, 1, outfile);
    fwrite(&db_creator, 4, 1, outfile);

    temp_long = LSwap(db_unique_id_seed);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    temp_long = LSwap(db_next_record_list_id);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);

    db_num_records = get_records() + 1;
    temp_short = SSwap(db_num_records);
    fwrite(&temp_short, sizeof(temp_short), 1, outfile);

    offset += (db_num_records * 8);

    /* write the record index for the special first record */
    temp_long = LSwap(offset);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);
    fwrite(&rec_attributes, sizeof(rec_attributes), 1, outfile);
    temp_char = 20;
    fwrite(&temp_char, sizeof(temp_char), 1, outfile);
    temp_char = 0;
    fwrite(&temp_char, sizeof(temp_char), 1, outfile);
    temp_char = 0;
    fwrite(&temp_char, sizeof(temp_char), 1, outfile);
    offset += 6;

    /* write the record indeces for the text records */
    for (i = 0; i < db_num_records - 1; i++) {
    temp_long = LSwap(offset);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);
    fwrite(&rec_attributes, sizeof(rec_attributes), 1, outfile);
    temp_char = 20;
    fwrite(&temp_char, sizeof(temp_char), 1, outfile);
    temp_char = ((i+1) & 0xff00) >> 8;
    fwrite(&temp_char, sizeof(temp_char), 1, outfile);
    temp_char = ((i+1) & 0x00ff);
    fwrite(&temp_char, sizeof(temp_char), 1, outfile);
    offset += strlen(record[i]) + 1;
    }

    fwrite(&pad, 2, 1, outfile);

    /* write the special first record */
    temp_long = LSwap(mode);
    fwrite(&temp_long, sizeof(temp_long), 1, outfile);
    temp_short = SSwap(last_used);
    fwrite(&temp_short, sizeof(temp_short), 1, outfile);

    /* write the text records */
    for (i = 0; i < db_num_records - 1; i++) {
    fwrite(record[i], strlen(record[i]) + 1, 1, outfile);
    }

    fclose(outfile);
    }
    }

    /************************************************** **************************
    * FUNCTION: get_records
    *
    * DESCRIPTION: reads the text records from the input file into a buffer,
    * transforming "\n" to the linefeed character (0x0a)
    ************************************************** **************************/
    long get_records(void)
    {
    FILE *infile;
    int rec_count = 0;
    char buf[MAX_LINE_LENGTH];

    infile = fopen(infile_name, "rt");
    if (infile) {
    while (!feof(infile) && (rec_count < MAX_RECORDS)) {
    memset(buf, 0, MAX_LINE_LENGTH);
    fgets(buf, MAX_LINE_LENGTH, infile);
    if (strlen(buf)) {
    printf("processing record %d\n", rec_count + 1);
    record[rec_count] = transform(buf);
    rec_count++;
    }
    }
    fclose(infile);
    }
    return(rec_count);
    }

    /************************************************** **************************
    * FUNCTION: LSwap
    *
    * DESCRIPTION: transforms an INTEL-architecture long int into a MOTOROLLA-
    * architecture long int.
    ************************************************** **************************/
    unsigned long LSwap(unsigned long l)
    {
    unsigned short temp_s1, temp_s2;
    unsigned long temp_l;

    temp_s1 = SSwap((unsigned short)((l & 0xffff0000) >> 16));
    temp_s2 = SSwap((unsigned short)(l & 0x0000ffff));
    temp_l = ((unsigned long)temp_s2 << 16) + temp_s1;
    return(temp_l);
    }

    /************************************************** **************************
    * FUNCTION: SSwap
    *
    * DESCRIPTION: transforms an INTEL-architecture short int into a MOTOROLLA-
    * architecture short int.
    ************************************************** **************************/
    unsigned short SSwap(unsigned short s)
    {
    unsigned short temp;

    temp = ((s & 0xff00) >> 8) + ((s & 0x00ff) << 8);
    return(temp);
    }

    /************************************************** **************************
    * FUNCTION: transform
    *
    * DESCRIPTION: transforms the passed string, converting "\n" to 0x0a (LF)
    ************************************************** **************************/
    char *transform(char *s)
    {
    char *temp_buf;
    char *s1 = s, *s2;
    unsigned char escape = FALSE;

    if (strlen(s) > 0) {
    temp_buf = (char *)malloc(strlen(s) + 1);
    memset(temp_buf, 0, strlen(s) + 1);
    s2 = temp_buf;
    while (*s1) {
    if (*s1 == '\\') {
    escape = TRUE;
    }
    else if (*s1 == LF) {
    }
    else {
    if ((*s1 == 'n') && escape) {
    *s2++ = LF;
    escape = FALSE;
    }
    else
    *s2++ = *s1;
    }
    s1++;
    }
    return(temp_buf);
    }
    }

    Question is why I cannot compile it ?

  2. #2
    Registered User
    Join Date
    Dec 2001
    Posts
    194
    Next time post the error messages you are getting to help us out.
    I found a few errors.
    1) Some of the comments have a space between the / and the first *
    This may just be because of the way you posted it, but make sure in your source file there is no space there.
    2) In the transform function you have this "if (*s1 == '\')"
    that should be '\\'
    remember \ starts an escape char such as \n or \r.
    Use \\ to get a single slash!

  3. #3
    Registered User
    Join Date
    Dec 2001
    Posts
    5

    this is my error message

    Thank you first of all for replying so fast and to remind me the basics I forgot to do .
    Here is the error message I get when using miracle compiler ( is it good or C... ?

    Thanks

  4. #4
    Registered User
    Join Date
    Dec 2001
    Posts
    5

    I must be stupid I forgot again

    here it is

    Miracle C Compiler (r3.2), written by bts.
    line 69: #include stdio.h ignored--file not found.
    line 70: #include stdlib.h ignored--file not found.
    line 71: #include string.h ignored--file not found.
    Compiling C:\Documents and Settings\andre\Desktop\mkmotd.c

    C:\Documents and Settings\andre\Desktop\mkmotd.c: line 96: incompatible types in initializer
    'unsigned long db_creation_date = 0x32cb1cc2'
    aborting compile


    Thanks

  5. #5
    Unregistered
    Guest
    I dont know anything about that compiler, but it can't find those include files, which are part of the ansi standard.
    Make sure the compiler is installed correctly, and the include files are where they should be.
    Sorry i can't help you any more.

  6. #6
    Registered User
    Join Date
    Nov 2001
    Posts
    32
    Dear Andy

    Thank you for your e-mail and link for the Borland C++ V5 compiler

    I went to the C Board and read your question.

    I have a few questions:
    1) Have you tried to compile and run this programme with the Borland complier that you have sent me the link to ?
    2) If so what is the result ?
    3) In the transform function you have this "if (*s1 == '\')". Can you tell me your intentions here. Was it to terminate a string with a NULL or to place a backslash into a string ?
    If your intentions were the first, then you need to add zero: "if (*s1 == '\0')".

    To eliminate a lot of errors I corrected your remarking syntax. This is the correct syntax for a remark in C.
    "/* this is a remark */"
    It is important that /* these two are together, no gaps and the same with these two */. It is useful (not necessary) that the remark be one space away from the beginning and the end. This makes it easier to read.
    So this is correct but less easy to read: "/*this is a remark*/".
    This is incorrect "/ * this is a remark * /" and will produce errors.
    This is incorrect "/ *this is a remark* /" and will produce errors.

    Next I was concerned about these messages:
    "Miracle C Compiler (r3.2), written by bts.
    line 69: #include stdio.h ignored--file not found.
    line 70: #include stdlib.h ignored--file not found.
    line 71: #include string.h ignored--file not found.
    Compiling C:\Documents and Settings\andre\Desktop\mkmotd.c

    C:\Documents and Settings\andre\Desktop\mkmotd.c: line 96: incompatible types in initializer
    'unsigned long db_creation_date = 0x32cb1cc2'
    aborting compile"

    The miracle complier does not recognise the three include files you have listed. Either because it does not have them or because they were not installed as a result of an error or because they have been removed.

    It is not uncommon that different versions of a compiler have such variations in them (it is very irritating when they do). Usually you can see the include files that will be recognised. They are contained in a folder called "include". Check here and see if the three you have declared are present. If they are not you can try and install again and then check again. If they are still not present then you have two options. Either try to get another compiler or try to find out which include files do the jobs you are trying to do. For example all functions with strings: copying etc are done via string.h.

    I have used several compilers and recently settled on a DOS version (Borland Turbo C++ Version 3 for DOS)(that can be run in Windows) that is ANSII standard and I have never had any compatibility issues with it. I can send this to you via four e-mails if you wish. The compiling I have done to your programme is via this version.

    Once the above issue is dealt with and you can compile, you will run into several warnings. I have reproduced in your code where the warnings appear. The first two warnings are related to the same function.

    You have declared main and not said whether it returns a value or not. Later you use "return(1);" in your coding.

    If you do want main to return a char or int then you should declare as follows
    "char main(int argc, char * argv[])" for a char return or
    "int main(int argc, char * argv[])" for an int return.

    If you do not want to return anything you should declare main as
    "void main(int argc, char * argv[])" and not have "return(1);" in your code.

    If it is your intentions to return a value that will be acted on after main has been executed then you need to know that "return(1);" is placed in the wrong position for this reasons. It is to do with how return works. Here is the official explanation:

    return (keyword). Exits immediately from the currently executing function to the calling routine, optionally returning a value.
    Syntax: return [ <expression> ] ;
    Example:
    double sqr(double x)
    {
    return (x*x);
    }

    Once the "return();" command is reached the code that comes after it in the same function will never be reached. So "break; will never execute. Nor will the lines of code that come after the case statement. To demonstrate this I have written a small programme called return.c and attached it to this e-mail. If it is your intentions that all code after the case statement in the main function be ignored then the code is sort of correct. If it is not your intentions that the code after the case statement be ignored then you have the return in the wrong place.

    To be accurate and to generate less warnings (warnings do not stop you running the programme but they are good clues to bad programming)it is more fruitful to place the ?return? at the end of the function. Make it the last thing that function does before that function ends.

    Because main() is declared without a return type, the compiler thinks that there should be a return value. Assuming you do not want to return a value then you should declare as a void: "void main(int argc, char * argv[])". This will stop any warnings about return values.


    Have some thoughts about the lengthy information I have given you. Let me know if you want a copy of the Borland V3 C++ compiler.

    Regards

    Stephen ([email protected])

Popular pages Recent additions subscribe to a feed