Don’t Be shy, let me know your choices, getopt();

Cuando se escriben programas para línea de comandos (programas de consola) es muy común tener que implementar una forma de parametrizar dicho programa al inicio, esto se logra pasando argumentos en la linea de comandos (Unix) al momento de ejecutar nuestro programa, en un principio solía escribir todo el código necesario para reconocer todos y cada uno de los argumentos, esto implicaba tener que recorrer un String analizando si existía en determinado String cada uno de los flags permitidos por el programa y analizar si el valor de dicho flag era valido para ese mismo flag, si bien esa tarea no es difícil si que es tediosa (al menos para mi que no me gustan las tareas repetitivas). Afortunadamente si estamos escribiendo nuestro programa en lenguaje C contamos con la función getopt() de la librería  <unistd.h> que nos simplificará muchísimo la tarea.

La funcion getopt(); tiene la siguiente sintaxis:

int  getopt(int argc, char * const argv[], const char *optstring);

Donde argc es un entero que representa el número de argumentos pasados al metodo main, *argv[] es el array de Strings pasados al metodo main,  y *optstring es un String que representa la configuración de que flags espera procesar la fución getopt() y si dichos flags deben tener un valor asociado o no.

La funcion getopt() regresa un entero que representa la opción actualmente procesada o -1 en caso de haber terminado de analizar todo el array de Strings determinado por el parametro *argv[],  cada vez que la función es llamada se incrementa un indice interno que apunta a los diferentes elementos del array de Strings determinado por el argumento *argv[].

Ademas de lo anterior, la funcion getopt(); establece las siguientes variables externas:

extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
extern int optreset;
  1. *optarg: Contiene el valor asociado a determinado flag si se ha espesificado que dicho flag admite valores, es decir, si se analiza el siguiente flag -f archivo.txt, *optarg contendra el valor archivo.txt
  2. optind: Contiene el indice del siguiente flag que se analizará en la siguiente llamada a la funcion getopt();
  3. optopt: Contiene el flag que actualmente esta siendo procesado.
  4. opterr: Si la función getopt(); encuentra un caracter que no esta espesificado en la cadena *optstring o detecta que falta el valor de un flag que debe tener un valor asociado escribira un mensaje de error en el flujo de salida stderr y retornara un valor ‘?’, para desactivar el mensaje de error en el flujo stderr tenemos que establecer el valor de opterr a 0 (cero).
  5. optreset: Es utilizada si queremos evaluar multiples grupos de argumentos o un grupo simple multiples veces.

Para indicar a la función getopt(); que flags debe reconocer y si esos flags tienen valores asociados debemos pasar un valor en forma de cadena al argumento *optstring, el valor de dicha cadena deben ser caracteres individuales representando a cado uno de los flags, un caracter independiente seguido de dos puntos indica que ese flag debe tener un valor asociado, de tal forma que:

"abc"

reconocerá los flags de la forma -a -b -c

y la cadena

"ab:c"

reconocerá los flags de la forma -a -b valor -c

ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
 
void usage();
 
int main ( int argc, char *argv[] )
{
  char *host;
  int  flagx;
  int  ch;
 
  host  = NULL;
  flagx = false;
 
  while( ( ch=getopt( argc, argv, "xh:" ) ) != -1 )
  {
     switch( ch )
     {
        case 'x':
               flagx = true;
               break;
        case 'h':
               host = (char *)malloc( strlen( optarg+1 ) );
               bzero( host, strlen( optarg+1 ) );
               strcpy( host, optarg );
               break;
        case '?':
               usage();
               return 0;
               break;
     }
  }
 
  printf( "-x = %d\n", flagx );
  printf( "-h = %s\n", host );
 
  free( host );
 
  return 1;
}
 
void usage()
{
    printf( "forma de uso:\n\t-x\n\t-h [nombre host|ip host]\n\n" );
}

aquí el resultado:

[espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble
-x = 0
-h = (null)
 
[espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -x
-x = 1
-h = (null)
 
[espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -x -h example.org
-x = 1
-h = example.org
 
[espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -h example.org -x
-x = 1
-h = example.org
 
[espartano@moscu ~/programas/C/pruebas]$ ./getoptexamble -x -h example.org -d
getoptexamble: illegal option -- d
forma de uso:
        -x
        -h [nombre host|ip host]
 
[espartano@moscu ~/programas/C/pruebas]$

Para mas informacion pueden leer la pagina del manual de la función  getopt(), man 3 getopt.

Posted under C, Programs, Unix by Espartano on Sunday 19 July 2009 at 9:28 pm

My favorite movies

The last week a friend asked me if I could suggest him some movies because he was boring, At that time I didn’t know what to answer him but I suddenly thought “He is an engineer sistem, He could enjoy some of my favorites movies about computers”, well here is my list of my favorites movies about computers, if you can get it I sure that you will enjoy it :)

Tron

tron

Tron is a cience fiction Disney’s movie from 1982 about a programer’s story that was “eaten” by a computer, The programer wake up into his machine immersed in his own video games in a fantastic world then he try to hack the main frame from his company to get evidence about an injustice.

WarGames

wargames

WarGames is a film from 1987 about a kid who obtain access to a pentagon’s computer (The kid doesn’t know where the computer is), that computer controls all nuclear weapons of USA but the kid believe that is only a video game, when the kid dicovers that he start to find out who had programed the computer to save the world.

pirates of silicon valley

pirates_of_sillicon_valley

Pirates of Sillicon Valley is a movie from 1999 based in a true history about how Bill Gates (Microsft) and Steve jobs (Apple) made revolutionary changes in the software and hardware industry, sometimes using lies to get his objetives.

Takedown

takedown

Takedown is the history (based in real facts) about the pursuit and capture of Kevin Mitnick who hacked a lot of companys getting its industrial secrets (according to the film), that was an incredible history of the ages when the internet started to be comercial net.

Antitrust

antitrust

Antitrus is a film about a young idealist and smart programmer called Milo Hoffman who make incredible softwares, he works in free way with his friends over a software that a big company wants and it will do anything to obtain the software.

The Matrix

the_matrix

I think that I don’t need to said anything about this film ;)

Sneakers

sneakersReally I can’t said anything about this film, it is a suggest from a friend to me but unfortunately I couldn’t get the film yet here in Mexico :( .

Haven’t you had enough? Ok these are some of my favorite films/documentals about computers:

The Code (codigo linux)

Part 2.

Part 3.

Part 4.

Part 5.

RevolutionOS

Part 2.

Part 3.

Part 4.

Part 5.

Part 6.

Part 7.

Part 8.

Part 9.

Piratas Informaticos

That is my favorite documental because it takes the history of Steve Wosniak, Captain Cruch, Kevin Mitnick and more…

Part 2.

Part 3.

Part 4.

Part 5.

Part 6.

There is another interesting documental but at this time I can’t remember the name of it but you be sure that when I remember it I will post it :) , I hope that if you are a computer lover you will enjoy all that films/documentals like me.

Posted under Documentals, Funny, History, Movies, Movies/films, Operating Systems, Programs, science by Espartano on Monday 8 June 2009 at 12:43 am

Lazy people works hard

Keep in mind that this is my first post in english, please if you see something written bad, let me know leaving a comment. well here we go.

some days ago I was very bored and tired at my job enough to do nothing that day, however I remembered that I would had to do one task, I needed to compare two databases to know what tables there was into the first one but not in the other one (each database had lots of tables), I’m a very very lazy person when I have to do humdrum tasks and that was definitely. I wouldn’t had wanted to acomplish that task reviewing table by table. I started to think how to do my task in a diferent way, suddenly an idea through across my mind, I would be able to list the name of all tables from each database then I could put all those names into a table containing only the names and making a SQL statement to group the names I would get group’s name, groups having only one element would be the result that I had been searching, but it all still was lot of work for my laziness, therefore I had to find out another way to solve my problem otherwise I would end doing it by hand and thought to myself “never mind, I never going to do that by hand”. It was the time when I remembered that Unix systems has lots of tools to manage text files maybe I could use something tools. Suddenly I remembered a command line tool called diff, the diff command compare two text files (actually it can be binary files) and show their differences, unfortunatly diff doesn’t do the work exactly as easy as I would like, by example having two files called db_one.txt and db_two.txt whit the name of the tables:

db_one.txt

table1
table2
table3
table4
table7
table9
table10

db_two.txt

table1
table2
table3
table4
table5
table6
table7
table8

Using diff command we would obtain this result:

[espartano@ ~/pruebas/diff]$ diff db_one.txt db_two.txt
4a5,6
table5
table6
6,7c8
table9
table10
---
table8
[espartano@ ~/pruebas/diff]$

but it doesn’t enough good for me, I would have liked a command more straightforward than diff (maybe with patch but I not remembered it in those times), well I had to continue searching a command that just make my work in a easy way, then was when I found the blessed command comm, yes, comm going to solve all my problem because as man page says:

utility comm reads file1 and file2, which should be sorted lexically, and produces three text columns as output: lines only in file1; lines only in file2; and lines in both files.


having the same two files from the last time:

[espartano@ ~/pruebas/diff]$ comm db_one.txt db_two.txt
                table1
                table2
                table3
                table4
        table5
        table6
                table7
        table8
 
table9
table10
 
[espartano@ ~/pruebas/diff]$

voiala this is the result that I was finding. At those point I wasn’t tired nor bored :) because I learned a couple new things, but I think that I worked more than what was do it by hand.

Only if you insist, this is the way which I would have done with SQL:

[espartano@ ~/pruebas/diff]$ cat db_two.txt >> db_one.txt
 
[espartano@ ~/pruebas/diff]$ cat db_one.txt
table1
table2
table3
table4
table7
table9
table10
 
table1
table2
table3
table4
table5
table6
table7
table8
 
[espartano@ ~/pruebas/diff]$ cat db_one.txt | sed -e s/^/"insert into tablas (nombre) values ('"/g > insert.sql
 
[espartano@ ~/pruebas/diff]$ cat insert.sql
insert into tablas (nombre) values ('table1
insert into tablas (nombre) values ('table2
insert into tablas (nombre) values ('table3
insert into tablas (nombre) values ('table4
insert into tablas (nombre) values ('table7
insert into tablas (nombre) values ('table9
insert into tablas (nombre) values ('table10
insert into tablas (nombre) values ('
insert into tablas (nombre) values ('table1
insert into tablas (nombre) values ('table2
insert into tablas (nombre) values ('table3
insert into tablas (nombre) values ('table4
insert into tablas (nombre) values ('table5
insert into tablas (nombre) values ('table6
insert into tablas (nombre) values ('table7
insert into tablas (nombre) values ('table8
insert into tablas (nombre) values ('
 
[espartano@ ~/pruebas/diff]$ cat insert.sql | sed -e s/$/"');"/g > completed_inserts.sql
 
[espartano@ ~/pruebas/diff]$ cat completed_inserts.sql
insert into tablas (nombre) values ('table1');
insert into tablas (nombre) values ('table2');
insert into tablas (nombre) values ('table3');
insert into tablas (nombre) values ('table4');
insert into tablas (nombre) values ('table7');
insert into tablas (nombre) values ('table9');
insert into tablas (nombre) values ('table10');
insert into tablas (nombre) values ('');
insert into tablas (nombre) values ('table1');
insert into tablas (nombre) values ('table2');
insert into tablas (nombre) values ('table3');
insert into tablas (nombre) values ('table4');
insert into tablas (nombre) values ('table5');
insert into tablas (nombre) values ('table6');
insert into tablas (nombre) values ('table7');
insert into tablas (nombre) values ('table8');
insert into tablas (nombre) values ('');
mysql>; CREATE DATABASE prueba;
Query OK, 1 row affected (0.13 sec)
 
mysql> USE prueba;
DATABASE changed
 
mysql> CREATE TABLE tablas (nombre varchar(50));
Query OK, 0 rows affected (0.42 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table1');
Query OK, 1 row affected (0.11 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table2');
Query OK, 1 row affected (0.03 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table3');
Query OK, 1 row affected (0.03 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table4');
Query OK, 1 row affected (0.03 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table7');
Query OK, 1 row affected (0.02 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table9');
Query OK, 1 row affected (0.01 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table10')
Query OK, 1 row affected (0.03 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('');
Query OK, 1 row affected (0.03 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table1');
Query OK, 1 row affected (0.06 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table2');
Query OK, 1 row affected (0.02 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table3');
Query OK, 1 row affected (0.02 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table4');
Query OK, 1 row affected (0.01 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table5');
Query OK, 1 row affected (0.03 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table6');
Query OK, 1 row affected (0.01 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table7');
Query OK, 1 row affected (0.01 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('table8');
Query OK, 1 row affected (0.02 sec)
 
mysql> INSERT INTO tablas (nombre) VALUES ('');
Query OK, 1 row affected (0.03 sec)

then

mysql> SELECT nombre FROM tablas GROUP BY nombre HAVING count(nombre) = 1;
+---------+
| nombre  |
+---------+
| table10 |
| table5  |
| table6  |
| table8  |
| table9  |
+---------+
5 rows IN SET (0.02 sec)
Posted under DataBases, Funny, Influenza, My life, Operating Systems by Espartano on Sunday 31 May 2009 at 9:06 pm

Tom Lane’s Funny T-Shirt

Tom Lane T-Shirt

Tom Lane T-Shirt

Yes, The man who appears in the picture is Tom Lane xD

Posted under DataBases, Funny, PostgreSQL, Programs by admin on Friday 22 May 2009 at 11:05 pm

Kasparov Vs. La maquina (Game Over)

Hace algunos días viendo  “The History channel” me encontré con un documental sobre las partidas que se llevaron a cabo en 1996 y 1997  entre el mejor jugador de ajedrez de todos los tiempos (Gary Kasparov) y una computadora patrocinada por la IBM (Deep Blue), el documental más que hablar de aspectos técnicos de como la computadora fue creada, programada o ensamblada o de jugadas estrategicas del ajedrez expone el lado humano y psicológico de la contienda, de como en teoría fue posible que la Deep Blue venciera a Kasparov, expone cuestiones extrañas y el extremo ermetismo del equipo de Deep Blue, de como la contienda amistosa y cientifica se convirtió en una guerra sin cuartel donde en teoría el objetivo principal fue destruir a kasparov, ¿o promocionar a la IBM? personalmente no lo sé pero a lo largo de todo el documental se mencionan y analizan hechos de lo más extraños, como a kasparov se le fue negado a ciertos informes acerca de Deep Blue, como Deep Blue jugó de una forma tan diferente entre el primer y segundo juego, el porqué de tanta seguridad en el lugar de la partida, etc etc.  Kasparov afirma que al principio la IBM no estaba inmersa directamente en el asunto pero que se vio interesada al ver la enorme publicidad que el evento estaba generando, recuerdo que en aquel año pensé que la I.A. había dado un paso enorme puesto que una maquina había logrado derrotar al campeón mundial de ajedrez, hoy tengo mis reservas, tal vez la maquina haya logrado calcular excepcionalmente bien sus movimientos, tal vez se hayan programado muy detalladamente las estrategias de Deep Blue, o tal vez el stress psicológico y la ansiedad de kasparov haya hecho la diferencia, estaría más convencido de que la maquina fue la campeona si no fuera porque se le negó a kasparov una revancha para poder “recuperar” su titulo, ¿y ustedes que opinan sobre el tema?

para quienes quieran ver el documental:

Posted under History, Programs, science by Espartano on Sunday 17 May 2009 at 8:26 pm